#include <iostream>
#include <vector>
using namespace std;
void swap(vector<int>&vec, int i, int j)
{
vec[i] = vec[i] ^ vec[j];
vec[j] = vec[i] ^ vec[j];
vec[i] = vec[i] ^ vec[j];
}
void heapInsert(vector<int>&vec, int index)
{
//判断堆的当前节点是否大于根节点
while (vec[index] > vec[(index - 1) / 2])
{
//如果大于,交换
swap(vec, index, (index - 1) / 2);
//交换完后更新index
index = (index - 1) / 2;
}
}
void adjustheap(vector<int>&vec, int index, int length)
{
int left = index * 2 + 1;
while (left < length)
{
//先比叫左孩子和右孩子的的大小,求出自己和左右孩子谁最大,并保留最大的那个坐标
int largest = left + 1 < length && vec[left] < vec[left + 1] ? left+1: left;
largest = vec[index]>vec[largest] ? index : largest;
//如果自己是最大的,那么就不需要在调整了
if (largest == index)
{
break;
}
//交换两个数位置
swap(vec, index, largest);
//更新index
index = largest;
//更新left
left = index * 2 + 1;
}
}
int main()
{
vector<int> vec{ 1, 3, 9, 4, 5, 10 };
//首先根据数据建立大根堆
for (int i = 0; i < vec.size(); i++)
heapInsert(vec, i);
//使得最大元素在数组最后一个位置,然后堆得size减一,重新将堆调整大根堆
for (int i = vec.size() - 1; i>0; i--)
{
swap(vec, 0, i);
adjustheap(vec, 0, i);
}
for (auto it : vec)
{
cout << it << " ";
}
}
以下是建堆得过程
下图为交换,重新建堆得过程(只画了第一次)
堆排序得时间复杂度O(N*logN),空间复杂度为O(1)
建堆时间得时间复杂度为O(N) (log1+log2+.....logN==N)
STL 里面得优先级队列priorty_queue就是堆结构