#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100;
//用数组来存储完全二叉树,第一个结点从1开始
int heap[maxn] = {0, 85, 55, 82, 57, 68, 92, 99, 98, 66, 56};
int n = 10;
//low为欲调整结点的数组下标,在[low, high]范围进行向下调整
void downAdjust(int low, int high){
int i = low, j = i * 2; //i为欲调整结点,j为其左孩子
while(j <= high){ //存在孩子结点
//如果右孩子存在,且右孩子的值大于左孩子
if(j + 1 <= high && heap[j + 1] > heap[j]){
j = j + 1; //让j存储右孩子下标
}
//如果孩子中最大的权值比欲调整结点i大
if(heap[j] > heap[i]){
swap(heap[j], heap[i]); //交换最大权值的孩子与欲调整结点i
i = j; //保持i为欲调整结点、j为i的左孩子
j = i * 2;
} else {
break; //孩子的权值均比欲调整结点i小,调整结束
}
}
}
void createHeap(){
for(int i = n / 2; i >= 1; i--){ //倒着枚举非叶子结点
downAdjust(i, n);
}
}
void deleteTop(){
heap[1] = heap[n--]; //用最后一个元素覆盖堆顶元素,并让元素个数减1
downAdjust(1, n);
}
void upAdjust(int low, int high){
int i = high, j = i / 2; //i为欲调整结点,j为其父亲
while(j >= low){ //父亲在[low,high]范围内
//父亲权值小于欲调整结点i的权值
if(heap[j] < heap[i]){
swap(heap[j], heap[i]); //交换父亲和欲调整结点
i = j; //保持i为欲调整节点、j为i的父亲
j = i / 2;
} else {
break; //父亲权值比欲调整结点i的权值大,调整结束
}
}
}
void insert(int x){
heap[++n] = x; //让元素个数加1,将数组末位赋值为x
upAdjust(1, n); //向上调整新加入的结点n
}
//堆排序
void heapSort(){
createHeap();
for(int i = n; i > 1; i--){
swap(heap[i], heap[1]);
downAdjust(1, i - 1);
}
}
int main(){
createHeap();
insert(111);
for(int i = 1; i <= n; i++){
printf("%d ", heap[i]);
}
printf("\n");
deleteTop();
for(int i = 1; i <= n; i++){
printf("%d ", heap[i]);
}
printf("\n");
heapSort();
for(int i = 1; i <= n; i++){
printf("%d ", heap[i]);
}
return 0;
}
堆的基本操作
最新推荐文章于 2022-07-06 22:05:31 发布