1006_堆排序
作者:互联网
堆排序
(实际上是调整好的一个最小堆)
题解
#include<iostream>
using namespace std;
int main() {
bool adjust = false; //用于控制循环,因为一轮并不一定能够完成最小堆的构建or调整
int m;
cin >> m;
for (int i = 0; i < m; i++) {
int n;
cin >> n;
int* num;
num = new int[n];
for (int j = 0; j < n; j++)
cin >> num[j];
do {
adjust = false; //中止条件,若一轮扫描没有结点的调整,则停止(有点冒泡的感觉)
//下面分了奇数和结点和偶数个结点的情况讨论
//基数个结点的话,最后一个是右孩子,需要先和左孩子比较
//偶数个结点的话最后一个是左孩子,这是一个特殊的局部,可以先处理
if (n % 2 == 0) {
if (num[n - 1] < num[(n / 2) - 1]) {
int exch = num[n - 1];
num[n - 1] = num[(n / 2) - 1];
num[(n / 2)-1] = exch;
adjust = true;
}
for (int u = n - 2; u > 0; u-=2) { //处理好上面的局部之后就是一个统一的处理了,u-=2是每次处理左右两个孩子和其父节点这个整体
int min;
int parent = (u + 1) / 2 - 1;
int id;
if (num[u] < num[u - 1]) { min = num[u]; id = u; }
else { min = num[u - 1]; id = u - 1; }
if (min < num[parent]) {
int exch = num[id];
num[id] = num[parent];
num[parent] = exch;
adjust = true;
}
}
}
else {
for (int u = n - 1; u > 0; u-=2) {
int min;
int parent = (u + 1) / 2 - 1;
int id;
if (num[u] < num[u - 1]) { min = num[u]; id = u; }
else { min = num[u - 1]; id = u - 1; }
if (min < num[parent]) {
int exch = num[id];
num[id] = num[parent];
num[parent] = exch;
adjust = true;
}
}
}
} while (adjust);
for (int k = 0; k < n; k++) {
cout << num[k] << ' ';
if (k + 1 == n)
cout << endl;
}
}
}
标签:parent,min,int,堆排序,num,1006,id,exch 来源: https://blog.csdn.net/weixin_45153966/article/details/120594618