zoukankan      html  css  js  c++  java
  • 优先队列:左式堆

    1、NPL(零路径长):从x到一个没有儿子的节点的最短路径的长。

    具有一个或者0个儿子的节点的NPL为0,NPL(NULL)=-1。

    任意节点的零路径长比它的儿子的零路径长的最小值多1。

    2、左式堆

    (1)满足二叉堆的所有性质。

    (2)对于堆的每一个节点x,左儿子的零路径长度至少与右儿子的零路径长度一样大(即NPL(Left)>=NPL(Right))

    3、性质:

    在右路径上有r个节点的左式树至少有2^r-1个节点。

    (N个节点的左式树的一条右路径最多含有log(N+1)个节点)

    4、具体操作:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    struct Node{
        int data,Npl;
        struct Node *Left,*Right;
    }; 
    typedef struct Node* PriorityQueue;
    PriorityQueue Merge1(PriorityQueue Q1,PriorityQueue Q2);
    
    bool IsEmpty(PriorityQueue Q) //与二叉堆的判断是否为空的方式相同 
    {
        return Q==NULL;
    }
    
    PriorityQueue Merge(PriorityQueue Q1,PriorityQueue Q2) //合并两个左式堆 
    {
        if(Q1==NULL) return Q2;
        if(Q2==NULL) return Q1;
        if(Q1->data<Q2->data) return Merge1(Q1,Q2);
        else return Merge1(Q2,Q1);
    }
    
    PriorityQueue Merge1(PriorityQueue Q1,PriorityQueue Q2)
    {
        if(Q1->Left==NULL) Q1->Left=Q2;
        else{
            Q1->Right=Merge(Q1->Right,Q2);
            if(Q1->Left->Npl<Q1->Right->Npl){
                PriorityQueue tp=Q1->Left;
                Q1->Left=Q1->Right;
                Q1->Right=tp;
            }
            Q1->Npl=Q1->Right->Npl+1;
        }
        return Q1;
    }
    
    PriorityQueue Insert1(int x,PriorityQueue Q) //插入 
    {
        PriorityQueue tp=new Node;
        if(tp==NULL) printf("Out of Space!!!
    ");
        else{
            tp->data=x;tp->Left=tp->Right=0;
            tp->Npl=1;
            Q=Merge(tp,Q);
        }
        return Q;
    }
    
    PriorityQueue DeleteMin1(PriorityQueue Q) //删除最小值,就是出队 
    {
        PriorityQueue Left,Right;
        if(IsEmpty(Q)){
            printf("The Priority Queue is Empty!!!
    ");
        }
        else{
            Left=Q->Left;
            Right=Q->Right;
            free(Q);
            return Merge(Left,Right);
        }
        return Q;
    }
    void Print(PriorityQueue Q) //输出最终结果 
    {
        if(Q){
            Print(Q->Left);
            printf("%d ",Q->data);
            Print(Q->Right);
        }
    }
    int main(void)
    {
        PriorityQueue Q1=NULL,tp,Q2=NULL;
        int n,m,i,x;
        cin>>n;
        for(i=0;i<n;i++){
            scanf("%d",&x);
            Q1=Insert1(x,Q1);
        }
        Print(Q1);cout<<endl;
        
        cin>>m;
        for(i=0;i<m;i++){
            scanf("%d",&x);
            Q2=Insert1(x,Q2);
        }
        Print(Q2);cout<<endl;
        
        tp=Merge(Q1,Q2);
        Print(tp);cout<<endl;
        while(!IsEmpty(tp)){
            printf("%d ",tp->data);
            tp=DeleteMin1(tp);
        }
        return 0;
    }
    /*
    测试数据:
    4
    1 2 3 4
    6
    7 8 9 5 10 11 
    */
    View Code
  • 相关阅读:
    ES7/ES8 语法学习
    JavaScript中this对象原理简洁说明
    浅谈http协议
    各个浏览器之间常见的兼容性问题
    npm -v 报错:cannot find module 'core-util-is'
    对象遍历的几种方法
    Vue项目如何关闭Eslint检测
    axios 基本运用
    如何去掉vue路由中的#
    vue 父子组件、兄弟组件传值
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10338041.html
Copyright © 2011-2022 走看看