堆排序
堆排序就是将数组堆化,大根堆小根堆的根元素永远是最大或者最小的,于是我们取根元素然后调整堆,继续一下次的堆化,不断重复直到取完(或者只剩下根元素)。
此处采用大根堆,将根元素也就是数组的[0]元素不断放到数组的末尾。大根堆的实现可见大小根堆的实现。
#pragma once
//=============================基于根堆的应用--堆排序==========================
//其实就是初始化大根堆的过程 初始化后不断从堆中取出top()元素后pop() 直至堆空
//需要注意的是 与前面的maxHeap.h不同 在maxHeap.h中 我们构造了一个大小为:目标数组大小+1的堆数组heap
//且heap[0]不用 所以我们的下标包括树的根都是从1开始计数的 所以它的左右孩子分别为2*root和2*root+1
//此处我们为了堆排序的效率和性能 不重新分配一个堆数组了 直接在原数组中进行排序
//那么我们的下标包括根的下标就必须从0开始 且根的左右孩子分别为2*root+1和2*root+2
//同时对于根节点来说 heap.h中它的根节点就是child/2 但是此处它的根节点为(child-1)/2
template <typename T>
void heapSort(T arr[], size_t arrSize) {
--arrSize;//指向尾元素
//首先初始化为堆
for (int root = arrSize / 2; root >= 0; --root) {
int child = 2 * root + 1;//根的左孩子
T rootElement = arr[root];
while (child <= arrSize) {
if (child < arrSize && arr[child] < arr[child + 1])//选左右孩子中大的一个
++child;
if (rootElement > arr[child])//是否可以在该位置插入?
break;
//不可以。随后把左右孩子中大的一个存在arr[child/2]上,child移动到下一层的左孩子。
arr[