//时间复杂度 nlog2(n)
#include <iostream>
using namespace std;
void keepHeap(int data[], int heapsize, int k) //平衡堆
{
int left = 2*k+1; //左孩子
int right = 2*k+2; //右孩子比左孩子多1
int large = k; //根
//取孩子里面最大的和父亲比较
if(left<heapsize && data[left] > data[large]) //孩子没出未排好序的数组的边界 同时左孩子大于父亲
large = left;
if(right<heapsize && data[right] > data[large])
large = right;
if(large != k) //如果有孩子大于父亲
{
swap(data[k],data[large]);
keepHeap(data, heapsize, large); //递归调用 平衡替换后孩子的堆
}
}
void buildHeap(int data[], int heapsize) //第二个参数是数组大小
{
int i = (heapsize/2)-1; //取最后一个二叉树
while(i>=0) //从最后一个二叉树开始往左和上判断
{
keepHeap(data, heapsize, i);
i--;
}
}
//总是把最大的换到未排序数组的最后一个
void heapsort(int data[], int n) //n为数组大小
{
int heapsize = n;
buildHeap(data, heapsize);
for(int i=heapsize-1; i>0; i--)
{
swap(data[0],data[i]);
--heapsize;
keepHeap(data,heapsize,0);
}
}
int main(void)
{
int data[10]={43,2,90,54,13,88,23,25,64,10};
heapsort(data,10);
for(int i: data)
cout<<i<<" ";
}
buildHeap是建立大根堆 这样才可以每次平衡堆时取得最大的元素
keepHeap是平衡大根堆 让这个树永远是大根树
heapsort进行排序 把最大的元素依次加到尾部 就是从尾部开始逐渐减小 大根堆嘛 先找最大 再找次要大第三大.......