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#include #include #include 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 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 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!!!\n"); 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!!!\n"); } 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 >m; for(i=0;i data); tp=DeleteMin1(tp); } return 0;}/*测试数据:41 2 3 467 8 9 5 10 11 */