优先队列能够完成以下操作:
♣插入一个数值
♣按照某种条件获得数值,并且删除(如最大值,最小值)
二叉堆的结构:儿子的值一定不小于父亲的值,数的节点按从上到下,从左到右紧密排列。
二叉堆的操作:
♣插入:在堆的末位插入该数值,不断向上交换,直至当前位置的父亲节点小于等于该数值
♣删除:把堆中的最小值(根的位置)删除,把堆最后一个节点移植根的位置,再不断向下交换(如若有两个儿子,选择数值较小的交换),直至当前位置的儿子节点均大于等于它。
二叉堆的存储和普通的二叉树一样,通过数组来存储。我们来分析一下父子的关系:
若父亲所在下标为m,左儿子的下标为n*2+1,右儿子的下标为n*2+2;
若儿子所在的下标为n,父亲的下标为(n-2)/2。
1 /*最小堆*/ 2 #include<iostream> 3 #include<cstdio> 4 using namespace std; 5 const int MAXN=1000; 6 int heap[MAXN]; 7 int operate,x,size=-1; 8 9 void push() 10 { 11 size++; 12 heap[size]=x; 13 int i=size; 14 while (i>0) 15 { 16 int p=(i-1)/2; 17 if (heap[p]<=x) break; 18 heap[i]=heap[p]; 19 i=p; 20 } 21 heap[i]=x; 22 return; 23 } 24 25 void pop() 26 { 27 cout<<heap[0]<<endl; 28 x=heap[size]; 29 size--; 30 int i=0; 31 while (i*2+1<size)//表示当前节点至少有一个孩子 32 { 33 int sa=i*2+1,sb=i*2+2; 34 if (heap[sa]>=x && heap[sb]>=x) break; 35 if (sb<size && heap[sa]>heap[sb]) sa=sb;//莫忘在右孩子存在的情形下才执行该判断语句 36 heap[i]=heap[sa]; 37 i=sa; 38 } 39 heap[i]=x; 40 return; 41 } 42 43 int main() 44 { 45 while (scanf("%d%d",&operate,&x)) 46 { 47 if (operate==0) break; 48 if (operate==1) push(); 49 if (operate==2) pop(); 50 } 51 return 0; 52 }
时间: 2024-10-25 07:34:57