其他分享
首页 > 其他分享> > 1006_堆排序

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