用数组实现一个小根堆,并完成排序的操作。(具体请看注释)
堆的基本操作实际上就几种:
1.向下调整操作AdjustDown()
2.向上调整操作AdjustUp() (向堆中插入元素时用到)
3.建堆操作BuildHeap(),其中要不断调用AdjustDown()来维护堆的性质
4.弹出堆顶元素GetRoot(),之后也要用到AdjustDown()来维护堆
ps(关于建堆):如果一开始建堆时堆中已有元素,那么直接调用一次BuildHeap()即可构造一个初始堆;
另外,也可以通过一个一个地插入堆中元素来构造堆,这样就不用BuildHeap(),因为每次插入后,都通过向上调整维护了堆。。
cpp代码:
/***
the basic operation of small-root-heap
***/
#include<iostream>
#define SIZE 1001
using namespace std;
class HEAP{
private:
int num;//堆中结点数目
int A[SIZE];//存储堆的数组
public:
HEAP(){num=0;}
~HEAP(){}
void InsertHeap(int x){
A[++num]=x;//将元素x插入堆
AdjustUp(num);//向上调整
}
void BuildHeap(){
for(int i=num/2;i>0;i--){
AdjustDown(i);//反复调整堆
}
}
void AdjustUp(int k){//k为结点的序号
A[0]=A[k];//保存A[k]至哨兵元素
int i=k/2;//i为k的双亲
while(i>0&&A[0]<A[i]){//大根堆
A[k]=A[i];//双亲结点下调
k=i;
i=i/2;//继续向上走
}
A[k]=A[0];//哨兵放到现在的位置中
}//即元素只向上走一个枝条,最远走到根为止
void AdjustDown(int k){
A[0]=A[k];//暂存
for(int i=2*k;i<=num;i*=2){
if(i<num&&A[i]>A[i+1])i++;//取较小的儿子结点
if(A[0]<=A[i])break;//比较根和较小儿子的大小
else{
A[k]=A[i];//交换
k=i;//k向下走
}
}
A[k]=A[0];//值再填回去
}
int GetRoot(){//弹出堆顶元素,并向下调整堆
if(num==0)return -1;
int root=A[1];//先保存堆顶元素以便最后返回
int temp=A[num];//堆顶和堆底交换
A[num--]=A[1];//顶点数-1
A[1]=temp;
BuildHeap();//调整
return root;
}
int GetNum(){
return num;
}
int SetNum(int num){
this->num=num;
}
int isEmpty(){
if(num==0)return 1;
else return 0;
}
void print(){
for(int i=1;i<=num;i++){
cout<<A[i]<<" ";
}
cout<<endl;
}
};
int main(){
HEAP *heap=new HEAP();//指针时需要用new
heap->InsertHeap(87);
heap->InsertHeap(45);
heap->InsertHeap(78);
heap->InsertHeap(32);
heap->InsertHeap(17);
heap->InsertHeap(65);
heap->InsertHeap(53);
heap->InsertHeap(9);
int n=heap->GetNum();
for(int i=0;i<n;i++)cout<<heap->GetRoot()<<" ";
cout<<endl;
delete heap;
return 0;
}