堆的基本操作

点击查看代码
/*
输入样例:
10
20 30 90 40 70 60 80 10 100 50
*/
#include<cstdio>
#include<algorithm>
using namespace std;
#pragma warning(disable:4996)
const int maxn = 110; //最多100个结点
int n, heap[maxn] = { 0 }; //n是结点总数,heap[]存储堆中结点的权值(下标是结点编号,从0开始)

//对结点left进行向下调整,调整范围是[left,right],时间复杂度O(logn)
//left是本轮要调整的非叶子结点编号,right是堆中最后一个叶子结点编号
void downAdjust(int left, int right) {
	int i = left, j = i * 2 + 1; //i指向本轮要调整的非叶子结点,j指向i的较大的孩子结点(初始为左孩)
	while (j <= right) { //孩子结点没有超出边界,可以向下调整		
		if (j + 1 <= right && heap[j + 1] > heap[j]) { //如果i的右孩存在,且右孩权值大于左孩
			j = j + 1; //则j指向右孩
		}
		if (heap[j] > heap[i]) { //如果孩子权值大于父结点权值,则互换两个结点位置
			swap(heap[j], heap[i]); //互换结点权值
			i = j; //i指向孩子j
			j = i * 2 + 1; //j指向i的新孩子,准备下一轮调整
		}
		else { //如果孩子权值小于等于父结点权值,则非叶子结点left调整结束
			break; //结束向下调整算法
		}
	}
}

//建立大顶堆,时间复杂度O(n)
void createHeap() {		
	for (int i = n / 2 - 1; i >= 0; i--) { //非叶子结点编号范围是[0,n/2-1],从最后一个非叶子结点开始调整
		downAdjust(i, n - 1); //对结点i进行向下调整,调整范围是[i,n-1]
	}
}

//删除堆顶结点(即最大值),时间复杂度O(logn)
void deleteTop() { 
	heap[0] = heap[n - 1]; //用最后一个叶子结点覆盖堆顶结点当作删除操作
	n--; //结点个数减一		
	downAdjust(0, n - 1); //对新栈顶结点进行向下调整,保持大顶堆结构,调整范围[0,n-1]
}

//对heap[]在[left,right]范围进行向上调整,时间复杂度O(logn)
//left是堆顶结点的下标,right是本轮要调整结点的下标
void upAdjust(int left, int right) {
	int i = right, j = (i - 1) / 2; //i指向要调整的结点,j指向其父结点
	while (j >= left) { //只要父结点没有超出上边界就可以向上调整		
		if (heap[i] > heap[j]) { //如果要调整的结点权值大于其父结点权值,则互换两个结点
			swap(heap[j], heap[i]); //互换结点权值
			i = j; //i指向父结点j
			j = (i - 1) / 2; //j指向新的父结点,准备下一轮调整
		}
		else { //如果要调整的结点权值大于等于其父结点权值,则该结点调整完成,结束循环
			break;
		}
	}
}

//给大顶堆添加一个权值为x的新结点
void insert(int x) { 
	heap[n++] = x; //在末尾heap[n]中添加权值为x的新结点,然后堆中结点个数加一
	upAdjust(0, n - 1); //新结点编号为n-1,要对它进行向上调整,保持大顶堆结构,调整范围[0,n-1]
}

//堆排序,时间复杂度O(nlogn)
void heapSort() { 
	createHeap(); //建立大顶堆	
	for (int i = n - 1; i > 0; i--) { //从后往前遍历,当堆中只剩一个结点时结束
		swap(heap[0], heap[i]); //将堆顶结点(最大值)和heap[i]互换,每轮将当前堆中最大值移至数组末尾
		downAdjust(0, i - 1); //然后对新的堆顶结点进行向下调整,保持大顶堆结构,调整范围[1,i-1]
	}
}

int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d", &heap[i]);
	}

	return 0;
}

posted @ 2022-09-30 21:12  zhaoo_o  阅读(12)  评论(0编辑  收藏  举报