网站标题怎么改,自学网站建设哪个网站好,wordpress 小工具添加图片,免费logo图标在线制作堆排序的基本步骤#xff1a;#xff08;以从大到小的顺序排序为例#xff09;
1.构建大顶堆#xff08;每个结点的值都大于或等于其左右孩子结点的值#xff09;
2.排序#xff1a;每次堆顶的元素取出来#xff08;整个堆中值最大#xff09;#xff0c;与最后一个…堆排序的基本步骤以从大到小的顺序排序为例
1.构建大顶堆每个结点的值都大于或等于其左右孩子结点的值
2.排序每次堆顶的元素取出来整个堆中值最大与最后一个节点做交换使末尾元素最大
3.交换完之后需要重新维护堆中剩下的其他节点保证每次的堆顶都是最大值重复23直到序列完全有序 Code
//维护堆的性质
//大顶堆父节点的左右孩子都比父节点小
//小顶堆父节点的左右孩子都比父节点大
void heapify(vectorint nums, int n, int i)
{int large i;//保存父节点int left 2 * i 1;//左孩子int right 2 * i 2;//右孩子//判断左孩子是否比父节点大 大的话就更新父节点的下标if (leftn nums[left]nums[large])large left;//判断右孩子是否比父节点大 大的话就更新父节点的下标if (rightn nums[right]nums[large])large right;//到此已经找到了当前父节点和其左右孩子中最大的节点的下标//判断父节点的下标是否发生变化如果不相等说明左右孩子中有比父节点大的if (large ! i){//交换节点维护大顶堆swap(nums[large], nums[i]);//继续维护剩下的节点heapify(nums, n, large);}
}
void heapsort(vectorint nums, int n)
{//建堆从最后一个有孩子的父节点开始建立//这里为什么是i n / 2 - 1 因为左孩子的下标可以表示为2*i1,此时最后一个孩子的下标为n-1//推导过来找到最后一个有孩子的父节点的下标为n / 2 - 1for (int i n / 2 - 1; i 0; i--){heapify(nums, n, i);}//排序将大顶堆的顶与最后一个叶子节点进行交换也就是每次找到当前堆中最大的元素放在数组的最后面for (int i n - 1; i 0; i--){//交换swap(nums[i], nums[0]);//继续维护大顶堆中剩下节点要始终保持是大顶堆的顺序heapify(nums, i, 0);}
}
int main()
{int n;cin n;vectorint nums(n);for (int i 0; i n; i){cin nums[i];}heapsort(nums, n);cout 按升序顺序排序 endl;for (auto i : nums){cout i ;}return 0;
}
这里如果要按照从小到大的顺序进行堆排序的话只需要将维护堆的函数中if判断条件做一点小改动即可。
void heapify(vectorint nums, int n, int i)
{int small i;//保存父节点int left 2 * i 1;//左孩子int right 2 * i 2;//右孩子if (leftn nums[left]nums[small])small left;if (rightn nums[right]nums[small])small right;//判断父节点的下标是否发生变化if (small ! i){//交换节点维护大顶堆swap(nums[small], nums[i]);//继续维护剩下的节点heapify(nums, n, small);}
} 堆排序是不稳定的排序算法。
堆排序的时间复杂度Onlogn