优先队列:二项队列
1、二项队列:堆序树的集合,称为森林,堆序树中每一棵都是有约束的形式称为二项树。
2、性质:高度为k的二项树恰好有k个节点。
3、实现:
(1)结构:每个二项树包含数据、一个儿子及右兄弟,二项树中的诸儿子以递减次序排列。
(2)采用儿子-兄弟表示法。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; const int MaxTree = 1200; const int INF = 9999999; struct Node{ int data; struct Node *LeftChid,*NextSibling; }; typedef struct Node* Position; typedef Position BinTree; struct Collection{ int CurrentSize; struct Node* TheTrees[MaxTree]; }; typedef struct Collection* BinQueue; bool IsEmpty(BinQueue H) //判断是否为空 { return H->CurrentSize==0; } BinQueue Init() //初始化 { BinQueue Q=new Collection; if(Q==NULL) printf("Out of Space!!!\n"); return Q; } BinTree CombineTrees(BinTree T1,BinTree T2) //合并两个二项树 { if(T1->data>T2->data) return CombineTrees(T2,T1); T2->NextSibling=T1->LeftChid; T1->LeftChid=T2; return T1; } BinQueue Merge(BinQueue H1,BinQueue H2) //合并两个二项队列 { BinTree T1,T2,Carry=NULL; int i,j; if(H1->CurrentSize+H2->CurrentSize>MaxTree){ printf("Merge would exeed capcity!!!"); } H1->CurrentSize+=H2->CurrentSize; for(i=0,j=1;j<H1->CurrentSize;j*=2,i++){ T1=H1->TheTrees[i]; T2=H2->TheTrees[i]; switch(!!T1+2*!!T2+4*!!Carry){ case 0: break; //没有树 case 1: break; //只有T1 case 2://只有T2 H1->TheTrees[i]=T2; H2->TheTrees[i]=NULL; break; case 3: //只有T1,T2 Carry=CombineTrees(T1,T2); H1->TheTrees[i]=H2->TheTrees[i]=NULL; break; case 4: //只有Carry H1->TheTrees[i]=Carry; Carry=NULL; break; case 5: //只有T1和Carry Carry=CombineTrees(T1,Carry); H1->TheTrees[i]=NULL; break; case 6://只有T2和Carry Carry=CombineTrees(T2,Carry); H2->TheTrees[i]=NULL; break; case 7: //有T1,T2,Carry三个树 H1->TheTrees[i]=Carry; Carry=CombineTrees(T1,T2); H2->TheTrees[i]=NULL; break; } } return H1; } int DeleteMin(BinQueue H) //删除最小元 { int i,j,pos,MinItem; Position DeletedTree,OldRoot; BinQueue DeletedQueue; if(IsEmpty(H)){ printf("Empty binomial queue"); return -INF; } MinItem=INF; for(i=0;i<H->CurrentSize;i++){ if(H->TheTrees[i]&&H->TheTrees[i]->data<MinItem){ pos=i; MinItem=H->TheTrees[i]->data; } } DeletedTree=H->TheTrees[pos]; OldRoot=DeletedTree; DeletedTree=DeletedTree->LeftChid; free(OldRoot); DeletedQueue=Init(); DeletedQueue->CurrentSize=(1<<pos)-1; for(j=pos-1;j>=0;j--){ DeletedQueue->TheTrees[j]=DeletedTree; DeletedTree=DeletedTree->NextSibling; DeletedQueue->TheTrees[j]->NextSibling=NULL; } H->TheTrees[pos]=NULL; H->CurrentSize-=DeletedQueue->CurrentSize+1; Merge(H,DeletedQueue); return MinItem; } BinQueue Insert(int x,BinQueue Q) //插入 { BinQueue H=new Collection; if(H==NULL) printf("Out of Space"); else{ H->CurrentSize=1; BinTree T=new Node; T->data=x; T->LeftChid=T->NextSibling=NULL; H->TheTrees[0]=T; return Merge(Q,H); } return Q; } void Travel(BinTree T) //遍历树 { if(T){ BinTree tp=T; while(tp!=NULL){ printf("%d ",tp->data); Travel(tp->NextSibling); tp=tp->LeftChid; } } } void Print(BinQueue H) //打印二项队列 { if(H==NULL){ printf("ERROR\n"); return ; } for(int i=0;i<H->CurrentSize;i++) if(H->TheTrees[i]!=NULL){ Travel(H->TheTrees[i]); printf("\n"); } printf("\n"); } int main(void) { int n,i,x; BinQueue H1=Init(),H2=Init(); H1->CurrentSize=40; H2->CurrentSize=40; for(i=1;i<=4;i++){ H1=Insert(i,H1); } Print(H1); for(i=5;i<=9;i++){ H2=Insert(i,H2); } Print(H2); H1=Merge(H1,H2); Print(H1); return 0; }