零路径长:从X到一个不具有两个儿子的结点的最短路径的长。
性质:
任一结点的零路径长比他的诸儿子结点的零路径长的最小值多1
父节点属性值小于子节点属性值;
堆中的任何节点,其左儿子的零路径长>=右儿子的零路径长;的二叉树。
下面是左式堆的类型声明:
1 template <typename Comparable>
2 class LeftistHeap
3 {
4 public:
5 LeftistHeap();
6 LeftistHeap(const LeftistHeap & rhs);
7 ~LeftistHeap();
8
9 bool isEmpty() const;
10 const Comparable & findMin() const;
11
12 void insert(const Comparable & x);
13 void deleteMin();
14 void deleteMin(Comparable & minItem);
15 void makeEmpty();
16 void merge(LeftistHeap & rhs);
17
18 const LeftistHeap & operator=(const LeftistHeap & rhs);
19
20 private:
21 struct LeftistNode
22 {
23 Comparable element;
24 LeftistNode *left;
25 LeftistNode *right;
26 int npl;
27
28 LeftistNode(const Comparable & theElement,LeftistNode *lt = NULL,LeftistNode *rt = NULL,int np=0)
29 :element(theElement),left(lt),right(rt),npl(np)
30 {
31 }
32 };
33 LeftistNode *root;
34 LeftistNode * merge(LeftistHeap *h1,LeftistHeap *h2);
35 LeftistNode * merge1(LeftistHeap *h1,LeftistHeap *h2);
36
37 void swapChildren(LeftistHeap *t);
38 void reclaimMemory(LeftistHeap *t);
39 LeftistNode * clone(LeftistHeap *t) const;
40 }
合并左式堆的驱动实例:
void merge(LeftistHeap & rhs)
{
if(this == &rhs)
return;
root = merge(root,rhs.root );
rhs.root = NULL;
}
LeftistNode * merge(LeftistNode * h1,LeftistNode *h2)
{
if(h1 == NULL)
return h2;
if(h2 == NULL)
return h1;
if(h1->element < h2->element)
return mergel(h1,h2);
else
return mergel(h2,h1);
}
合并左式堆的实例:
1 LeftistNode * mergel(LeftistNode *h1,LeftistNode *h2)
2 {
3 if(h1->left == NULL)
4 h1->left = h2;
5 else
6 {
7 h1->right = merge(h1->right,h2);
8 if(h1->left->npl < h1->right->npl)
9 swapChildren(h1);
10 h1->npl = h1->right->npl + 1;
11 }
12 return h1;
13 }
左式堆的插入操作:
1 void insert(const Comparable & x)
2 {
3 root = merge(new LeftListNode(x),root);
4 }
左式堆的deleteMin操作:
1 void deleteMin()
2 {
3 if(isEmpty())
4 throw UnderflowException();
5 LeftistNode * oldRoot = root;
6 root = merge(root->left,root->right);
7 delete oldRoot;
8 }
9 void deleteMin(Comparable & minItem)
10 {
11 minItem = findMin();
12 deleteMin();
13 }
下面是左式堆的应用实例:
1 #ifndef LeftistHeap_h__
2 #define LeftistHeap_h__
3 #define NULL 0
4 // ******************公共操作*********************
5 // void insert( x ) --> 插入x
6 // deleteMin( minItem ) --> 删除最小元素
7 // Comparable findMin( ) --> 返回最小元素
8 // bool isEmpty( ) --> 为空返回true,否则返回false
9 // void makeEmpty( ) --> 清空
10 // void merge( rhs ) --> 合并rhs到本堆中
11 // ******************说明********************************
12 // 代码根据数据结构与算法分析中的代码编写
13 template <typename Comparable>
14 class LeftistHeap
15 {
16 public:
17 LeftistHeap():root(NULL)
18 {}
19 LeftistHeap(const LeftistHeap &rhs)
20 {
21 *this = rhs;
22 }
23 ~LeftistHeap()
24 {
25 makeEmtpy();
26 }
27 //插入x元素
28 void insert(const Comparable &x)
29 {
30 root = merge(new LeftistNode(x), root);
31 };
32 //为空返回true,否则返回false
33 bool isEmpty() const
34 {
35 return root == NULL;
36 }
37 //找到最小元素并返回其值
38 const Comparable& findMin() const
39 {
40 if(!isEmpty())
41 return root->element;
42 }
43 //删除最小元素
44 void deleteMin()
45 {
46 if(isEmpty())
47 return;
48 LeftistNode* oldroot = root;
49 root = merge(root->left, root->right);
50 delete oldroot;
51 }
52 //删除最小元素,并将其值赋予minItem
53 void deleteMin(Comparable &minItem)
54 {
55 minItem = findMin();
56 deleteMin();
57 }
58 //清空
59 void makeEmtpy()
60 {
61 reclaimMemory(root);
62 root = NULL;
63 }
64 //将另一个堆合并到本堆中
65 void merge(LeftistHeap &rhs)
66 {
67 if(this == &rhs)
68 return;
69 root = merge(root, rhs.root);
70 rhs.root = NULL;
71 }
72 const LeftistHeap& operator=(const LeftistHeap &rhs)
73 {
74 if(this != &rhs)
75 {
76 makeEmtpy();
77 root = clone(rhs.root);
78 }
79 return *this;
80 }
81 private:
82 struct LeftistNode
83 {
84 Comparable element;
85 LeftistNode *left;
86 LeftistNode *right;
87 int npl;
88 LeftistNode(const Comparable &e, LeftistNode *l = NULL,
89 LeftistNode *r = NULL, int n = 0)
90 :element(e), left(l), right(r), npl(n)
91 {}
92 };
93 LeftistNode *root;
94 //处理非一般情况,并递归调用merge1
95 LeftistNode* merge(LeftistNode *h1, LeftistNode *h2)
96 {
97 if(h1 == NULL)
98 return h2;
99 if(h2 == NULL)
100 return h1;
101 if(h1->element < h2->element)
102 merge1(h1, h2);
103 else
104 merge1(h2, h1);
105 }
106 //合并两个节点
107 //h1是具有最小元素的根节点
108 LeftistNode* merge1(LeftistNode *h1, LeftistNode *h2)
109 {
110 if(h1->left == NULL)
111 h1->left = h2;
112 else
113 {
114 h1->right = merge(h1->right, h2);
115 if(h1->left->npl < h1->right->npl)
116 swapChildren(h1);
117 h1->npl = h1->right->npl + 1;
118 }
119 return h1;
120 }
121 void swapChildren(LeftistNode *t)
122 {
123 LeftistNode *tmp = t->left;
124 t->left = t->right;
125 t->right = tmp;
126 }
127 void reclaimMemory(LeftistNode *t)
128 {
129 if(t != NULL)
130 {
131 reclaimMemory(t->left);
132 reclaimMemory(t->right);
133 delete t;
134 }
135 }
136 LeftistNode *clone(LeftistNode *t) const
137 {
138 if(t == NULL)
139 return NULL;
140 else
141 return new LeftistNode(t->element, clone(t->left), clone(t->right));
142 }
143 };
144 #endif // LeftistHeap_h__
1 #include "LeftistHeap.h"
2 #include <cstdlib>
3 #include <ctime>
4 #include <iostream>
5 using namespace std;
6 int main()
7 {
8 LeftistHeap<int> leftistHeapA, leftistHeapB, leftistHeapC;
9 srand((unsigned)time(0));
10 for(int i=0; i< 1000; i++)
11 {
12 int t = rand();
13 leftistHeapA.insert(t);
14 }
15 for(int i=0; i< 1000; i++)
16 {
17 int t = rand();
18 leftistHeapB.insert(t);
19 }
20 leftistHeapA.merge(leftistHeapB);
21 leftistHeapA.merge(leftistHeapC);
22 int t;
23 while(leftistHeapA.isEmpty() == false)
24 {
25 leftistHeapA.deleteMin(t);
26 cout<<t<<" ";
27 }
28 cout<<endl;
29 getchar();
30 return 0;
31 }
转载于:https://my.oschina.net/u/204616/blog/545035