堆是一种数据结构,注意不是二叉树,是数组结构,但是处理堆时可以看成完全二叉树,分为大根堆和小根堆。
一:首先初始化堆,保证每个root左右孩子的值均不大于它,且该点需对每个子树的root成立
//我这里是调整为大根堆
void init(vector<int>&v) {
for (int i = v.size() - 1; i > 0; i--) {
if (v[i] > v[(i - 1) / 2]) { //完全二叉树性质,若孩子结点大于父节点 交换
int j = i;
while (j>=0&&v[j] > v[(j - 1) / 2]) {
swap2(v, j, (j - 1) / 2);
j = (j - 1) / 2;
}
}
}
}
二:调整堆,由于是大根堆,根节点的值最大,应该出堆,出堆方法就是让其到此时堆的最后一个位置,最后一个位置来到堆顶。由于此时堆结构的性质被破坏,需要重新调整堆。
void heapify(vector<int>&v,int cur_size) {
int i = 0;
while ((2*i+1)<cur_size) {
int large = (2 * i + 2) < cur_size&&v[2 * i + 2] > v[2 * i + 1] ?( 2 * i + 2) : (2 * i + 1);
if (v[large] > v[i])
swap2(v, i, large);
i = large;
}
}
三:完整堆排序
void heapSort(vector<int>&v) {
init(v);
int cur_size = v.size();
while (cur_size) {
cout << v[0];
swap2(v,0,cur_size-1);
cur_size--;
heapify(v, cur_size);
}
}