堆以及优先队列
#include<iostream> using namespace std; int A[]={0,4,1,3,2,16,9,10,14,8,7}; int left(int i){ return 2*i; } int right(int i){ return 2*i+1; } int parent(int i){ return i/2; } void heap(int i){ int l=left(i); int r=right(i); int larget; if(l<=10&&A[l]>A[i]){ larget=l; } else larget=i; if(r<=10&& A[r]>A[larget]){ larget=r; } if(larget!=i){ int t=A[larget]; A[larget]=A[i]; A[i]=t; heap(larget); } } int main(){ //heap(2); //观察从第二个位置开始不符合最大堆的规定 //重建堆: for(int i=10/2+1;i>=1;i--){ heap(i); } for(int i=1;i<=10;i++){ cout<<A[i]<<endl; } system("pause"); return 0; } 重建堆,从非叶子节点的节点开始,自下而上地重建最大堆! 是维护最大堆方法的调用。 堆排序算法: } 堆以及优先队列的操作: #include<iostream> using namespace std; //int a[]={0,16,4,10,14,7,9,3,2,8,1}; int a[]={0,4,1,3,2,16,9,10,14,8,7}; int len=0; int left(int i){ return 2*i; } int right(int i){ return 2*i+1; } int partent(int i){ return i/2; } int length(){ for(int i=1;;i++){ if(a[i]!=0) len++; else break; } return len; } //维护堆的性质,n为出现不符合最大堆的位置,小于俩孩子结点的情况 int heap(int n){ int l,r,larget; l=left(n); r=right(n); if(a[n]<a[l]&&l<=len){ larget=l; }else larget=n; if(a[r]>a[larget]&&r<=len) larget=r; if(larget!=n){ int t=a[n]; a[n]=a[larget]; a[larget]=t; heap(larget); } return 0; } //建堆 void buildheap(){ //从叶子结点开始 for(int i=len/2;i>0;i--){ heap(i); } } //堆排序算法:最大元素为a[1],拿走最大元素,长度减一 void heapsort(){ buildheap(); //进行排序,使最大元素位于第一位 int leng=len; for(int i=leng;i>=2;i--){ int t=a[1]; a[1]=a[i]; a[i]=t; len--; heap(1); } } //以下的方法为优先队列 //得到最大元素:对于最大堆来说,最大元素为第一个 int Maximun(){ return a[1]; } //得到最大元素并去掉, int extact(){ int max=a[1]; a[1]=a[len]; len--; heap(1); return max; } //insert(x,k) 将x位置的数据增大k,增大到k可能会导致最大堆发生变化 void insert(int x,int k){ a[x]=k; if(x!=1){ while((x>1)&&(a[x]>a[partent(x)])){ //大于父母结点的孩子,这种情况比较简单,向上替换父母结点即可 int t=a[x]; a[x]=a[partent(x)]; a[partent(x)]=t; x=partent(x); } } } //将key插入集合中 void insertkey(int key){ len+=1; a[len]=-1000; insert(len,key); } int main(){ length(); int l=len; //heap(2); buildheap(); //insert(2,20); //cout<<Maximun()<<endl; //cout<<extact()<<"==="<<endl; //heapsort(); insertkey(15); for(int i=1;i<=l+1;i++){ cout<<a[i]<<endl; } system("pause"); return 0; }