zoukankan      html  css  js  c++  java
  • 优先队列:二项队列

    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!!!
    ");
        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
    ");
            return ;
        }
        for(int i=0;i<H->CurrentSize;i++)
            if(H->TheTrees[i]!=NULL){
                Travel(H->TheTrees[i]);
                printf("
    ");
            }
        printf("
    ");
    }
    
    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
  • 相关阅读:
    Javascript跨域后台设置拦截
    Hello ReactJS
    Redis 常用监控信息命令总结
    MySQL架构与业务总结图
    MySQL垂直拆分和水平拆分的优缺点和共同点总结
    MySQL实用工具汇总
    MySQL查看数据库表容量大小
    MySQL到底能支持多大的数据量?
    微信小程序wxss的background本地图片问题
    微信小程序中显示与隐藏(hidden)
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10338836.html
Copyright © 2011-2022 走看看