这个和上个版本类似,略有不同
//二叉堆(数组存储)的插入,删除堆顶元素(以小根堆为例,即堆顶元素最小)
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int Max_size = (int)1e3; //表示堆中能够容纳元素个数的最大值
int size = 0,Heap[Max_size]; //记录当前堆中元素下标最大值
//往堆中插入元素,数组下标从0开始
void push(int value){ //value表示插入堆的值
Heap[size] = value; //一开始元素接在堆的最后面
int current = size; //表示当前遍历到的节点
int father = (current-1) / 2; //表示当前遍历到的堆中元素的父亲节点的下标
while(current > 0 && Heap[current] < Heap[father]){
//表示此时节点"上溢",当前节点与其父节点对换.
swap(Heap[current],Heap[father]);
current = father;
father = (current-1) / 2; //继续向上遍历
}
++size;
}
/*
*删除栈顶元素
*删除栈顶元素时,不可直接将size的值减一后就结束,这样的话会破坏整个
*二叉堆的结构,因此我们在删除堆顶元素之后还要调整堆的结构,使其成为新的堆
*并且有新的堆顶元素
*/
int pop(){
int topHeap = Heap[--size];
Heap[0] = topHeap;
//首先将最后一个元素替换堆顶元素,这样的话堆顶元素则被删除,然后再是size减一表示堆中元素数目减一
int current = 0; //当前遍历到的节点的下标
int lchild = current*2 + 1; //当前遍历到的节点的左孩子和右孩子节点的下标
int rchild = current*2 + 2;
while(lchild < size && min(Heap[lchild],Heap[rchild]) < Heap[current])
{
if(Heap[lchild] < Heap[rchild]){
swap(Heap[lchild],Heap[current]);
current = lchild; //"下溢"的过程
}
else{
swap(Heap[rchild],Heap[current]);
current = rchild;
}
lchild = current*2 + 1;
rchild = current*2 + 2;
}
return topHeap;
}
//获取堆顶元素
int top(){
return Heap[0];
}
//输出堆中元素
void output(){
for(int i = 0;i < size;++i){
printf("%d ",Heap[i]);
}
printf("\n");
}
int main(){
int a[6];
cout<<"请输入堆中元素:";
for(int i = 0;i < 6;++i){
cin>>a[i];
push(a[i]);
}
printf("小根二叉堆堆顶元素为:%d\n",top());
cout<<"堆中所有元素为:"<<endl;
output();
return 0;
}