优先队列:二项队列

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;
}
View Code

 

posted @ 2019-01-30 16:53  麟阁  阅读(202)  评论(0编辑  收藏  举报