优先队列:左式堆

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
原文地址:https://www.cnblogs.com/2018zxy/p/10338041.html