输入数组长度n,再依次输入n个数,输出排序后的结果。
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int n, q[N];
//向下调整,low为欲调整的数组下标,high一般为堆的最后一个元素的数组下标,在[low, high]范围内进行调整
void down_adjust(int low, int high) {
int i = low, j = 2 * i;
while (j <= high) { //左孩子存在
if (j + 1 <= high && q[j + 1] > q[j]) { //右孩子存在,且右孩子的值比左孩子大
j = j + 1; //此时的j为左右孩子中值较大的那个孩子的下标
}
if (q[j] > q[i]) { //左右孩子中较大的那个值q[j]比当前要调整的数q[i]大
swap(q[i], q[j]); //交换
//继续往下调整
i = j;
j = 2 * j;
} else {
break; //当前元素q[i]比左右孩子都大,调整完毕,结束循环
}
}
}
//构造大顶堆
void create_heap() {
//从最后一个数的父节点开始往前调整
for (int i = n / 2; i >= 1; i -- ) down_adjust(i, n);
}
//堆排序
void heap_sort() {
create_heap(); //建堆
/*
将堆顶元素(最大)与当前最后一个元素q[i]替换,直至堆顶,
再进行一次针对堆顶元素的向下调整(保证交换后除了当前最后一个元素还是大顶堆),
直到堆中只有一个元素为止(每次都将最大值放到最后,从后往前遍历,保证结束后整个序列是正序的)
*/
for (int i = n; i > 1; i -- ) { //当只有一个元素不需要交换调整,结束循环
swap(q[i], q[1]); //当前最后一个元素和堆顶元素进行交换
down_adjust(1, i - 1); //针对堆顶元素向下调整
}
}
int main() {
cin >> n;
//下标从1开始一直到n
for (int i = 1; i <= n; i ++ ) cin >> q[i];
heap_sort();
for (int i = 1; i <= n; i ++ ) cout << q[i] << " ";
return 0;
}
如有问题,欢迎留言交流~