左式二叉堆

定义:

零路径长Npl(x):定义为从X到一个没有两个儿子的节点的最短路径长。 Npl(X) = min{ Npl(lchild), Npl(rchild) } + 1 (定义Npl(NULL) = -1,那么这个公式满足只有一个子节点的节点)

左式堆的性质:1、结构性质(对于堆中的任一节点,左儿子的零路径长至少与右儿子的零路径长一样大) 2、堆序性质:和二叉树的相同,节点的值大于等于其父节点的值

 

一些有趣的结论:

1、左式堆的零路径就是沿着节点的右路径,否则,如果存在一条零路径并取得左儿子,说明Npl(lchild) < Npl(rchild),破坏了左式堆的结构性质。

2、在根节点右路径上有r个节点的左式堆必然至少有2- 1个节点。

 

左式堆的操作:

对左式堆的基本操作是合并,注意插入只是合并的基本操作。

 

数据结构定义如下:

 1 struct TreeNode;
 2 typedef struct TreeNode *PriorityQueue;
 3 
 4 PriorityQueue Initialize();
 5 ElementType FindMin(PriorityQueue H);
 6 int Empty(PriorityQueue H);
 7 PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2);
 8 
 9 #define Insert(X, H) (H = Insert1((X), H));
10 #define DeleteMin1(H) (H->Element;H = DeleteMin1(H);)
11 
12 PriorityQueue Insert1(ElementType X, PriorityQueue H);
13 PriorityQueue DeleteMin1(PriorityQueue H);

 

Merge实现代码如下:

 1 PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2){
 2     if(H1 == NULL)
 3         return H2;
 4     if(H2 == NULL)
 5         return H1;
 6     if(H1->Element <= H2->Element)
 7         return Merge1(H1, H2);
 8     else
 9         return Merge1(H2, H1);
10 }
11 
12 PriorityQueue Merge1(PriorityQueue H1, PriorityQueue H2){
13     if(H1->Left == NULL)
14         H1->Left = H2;
15     else{
16         H1->Right = Merge(H1->Right, H2);
17 
18         if(H1->Left->Npl < H1->Right->Npl)
19             SwapChildren(H1);
20         H1->Npl = H1->Right->Npl + 1;
21     }
22     return H1;
23 }

 

Insert1实现代码如下:(Insert的宏定义是为了和堆的Insert的函数的使用方式一样)

1 PriorityQueue Insert1(ElementType X, PriorityQueue H){
2     PriorityQueue H1 = malloc(sizeof(struct TreeNode));
3     H1->Left = H1->Right = NULL;
4     H1->Npl = 0;
5     H1->Element = X;
6     return Merge(H1, H);
7 }

 

DeleteMin1实现代码如下:(DeleteMin的宏定义与Insert的意义类似)

1 PriorityQueue DeleteMin1(PriorityQueue H){
2     PriorityQueue H1, H2;
3     H1 = H->Left;
4     H2 = H->Right;
5     free(H);
6     return Merge(H1, H2);
7 }

 

posted @ 2018-04-15 09:45  赵永驰  阅读(152)  评论(0编辑  收藏  举报