左式堆的實現與詳解


定義:左式堆(Leftist Heaps)又稱作最左堆、左傾堆,是計算機語言中較為常用的一個數據結構。左式堆作為堆的一種,保留了堆的一些屬性。第1,左式堆仍然以二叉樹的形式構建;第2,左式堆的任意結點的值比其子樹任意結點值均小(最小堆的特性)。但和一般的二叉堆不同,左式堆不再是一棵完全二叉樹(Complete tree),而且是一棵極不平衡的樹。

性質:

零路徑長:從X到一個不具有兩個兒子的結點的最短路徑的長。

1. 任一結點的零路徑長比他的諸兒子結點的零路徑長的最小值多1

2. 父節點屬性值小於子節點屬性值;

3. 堆中的任何節點,其左兒子的零路徑長>=右兒子的零路徑長的二叉樹。

操作:

左式堆的操作都是基於合並,而合並僅對右路做合並,而右路結點的數量為總數量的對數關系,所以左式堆的三個操作(合並,刪除,插入)所花的時間為O(logN).

左式堆的合並操作基於遞歸完成,算法如下:

1.如果有一棵樹是空樹,則返回另一棵樹;否則遞歸地合並根結點較小的堆的右子樹根結點較大的堆

2.使形成的新堆作為較小堆的右子樹。

3.如果違反了左式堆的特性,交換兩個子樹的位置。
4.更新Npl。

 刪除最小值/最大值:

刪除操作的做法相當的簡單,刪除左式堆的根節點,合並左右子樹即可。

插入:將需要插入的節點當做一棵左式堆樹,進行合並即可。

 

下面給出左式堆的c++類模板實現

  1 #include <iostream>
  2 using namespace std;
  3 
  4 template <typename Comparable>
  5 class LeftistHeap
  6 {
  7 public:
  8     LeftistHeap() :root(NULL){}
  9     LeftistHeap(const LeftistHeap &rhs)
 10     {
 11         *this = rhs;
 12     }
 13     ~LeftistHeap()
 14     { 
 15         MakeEmpty(); 
 16     }
 17 
 18     bool IsEmpty() const;
 19     const Comparable &FindMin() const;
 20 
 21     void Insert(const Comparable &x);
 22     void DeleteMin();
 23     void DeleteMin(Comparable &minItem);
 24     void MakeEmpty();
 25     void Merge(LeftistHeap &rhs);
 26 
 27     const LeftistHeap &operator=(const LeftistHeap &rhs);
 28 
 29 private:
 30     struct LeftistNode
 31     {
 32         Comparable element;
 33         LeftistNode *left;
 34         LeftistNode *right;
 35         int npl;
 36 
 37         LeftistNode(const Comparable &theElement, LeftistNode *lt = NULL, LeftistNode *rt = NULL, int np = 0) :
 38             element(theElement), left(lt), right(rt), npl(np){}
 39     };
 40     LeftistNode *root;
 41 
 42     LeftistNode *Merge(LeftistNode *h1, LeftistNode *h2);
 43     LeftistNode *Merge1(LeftistNode *h1, LeftistNode *h2);
 44 
 45     void SwapChildren(LeftistNode *t);
 46     void ReclaimMemory(LeftistNode *t);
 47     LeftistNode *Clone(LeftistNode *t) const
 48     {
 49         if (t == NULL)
 50             return NULL;
 51         else
 52             return new LeftistNode(t->element, clone(t->left), clone(t->right));
 53     }
 54 
 55 };
 56 
 57 
 58 
 59 template <typename Comparable>
 60 bool LeftistHeap<Comparable>::IsEmpty() const
 61 {
 62     return root == NULL;
 63 }
 64 
 65 template <typename Comparable>
 66 void LeftistHeap<Comparable>::Insert(const Comparable &x)
 67 {
 68     root = Merge(new LeftistNode(x), root);
 69 }
 70 
 71 template <typename Comparable>
 72 void LeftistHeap<Comparable>::Merge(LeftistHeap &rhs)
 73 {
 74     if (this == &rhs)//避免和自己合並
 75         return;
 76     root = Merge(root, rhs.root);
 77     rhs.root = NULL;
 78 }
 79 
 80 template <typename Comparable>
 81 void LeftistHeap<Comparable>::SwapChildren(LeftistNode *t)
 82 {
 83     LeftistNode *tmp = t->left;
 84     t->left = t->right;
 85     t->right = tmp;
 86 }
 87 
 88 template <typename Comparable>
 89 typename LeftistHeap<Comparable>::LeftistNode *LeftistHeap<Comparable>::Merge1(LeftistNode *h1, LeftistNode *h2)
 90 {
 91     if (h1->left == NULL)
 92         h1->left = h2;
 93     else
 94     {
 95         h1->right = Merge(h1->right, h2);
 96         if (h1->left->npl < h1->right->npl)
 97             SwapChildren(h1);
 98         h1->npl = h1->right->npl + 1;
 99     }
100     return h1;
101 }
102 
103 template <typename Comparable>
104 typename LeftistHeap<Comparable>::LeftistNode *LeftistHeap<Comparable>::Merge(LeftistNode *h1, LeftistNode *h2)
105 {
106     if (h1 == NULL)
107         return h2;
108     if (h2 == NULL)
109         return h1;
110     if (h1->element < h2->element)
111         return Merge1(h1, h2);
112     else
113         return Merge1(h2, h1);
114 }
115 
116 
117 
118 
119 
120 template <typename Comparable>
121 void LeftistHeap<Comparable>::DeleteMin()
122 {
123     if (IsEmpty())
124         return;
125     LeftistNode *oldRoot = root;
126     root = Merge(root->left, root->right);
127     delete oldRoot;
128 }
129 
130 
131 template <typename Comparable>
132 void LeftistHeap<Comparable>::DeleteMin(Comparable &minItem)
133 {
134     minItem = FindMin();
135     DeleteMin();
136 }
137 
138 template <typename Comparable>
139 const Comparable & LeftistHeap<Comparable>::FindMin() const
140 {
141     if (!IsEmpty())
142         return root->element;
143 }
144 
145 
146 template <typename Comparable>
147 void LeftistHeap<Comparable>::ReclaimMemory(LeftistNode *t)
148 {
149     if (t != NULL)
150     {
151         ReclaimMemory(t->left);
152         ReclaimMemory(t->right);
153         delete t;
154     }
155 }
156 
157 
158 template <typename Comparable>
159 void LeftistHeap<Comparable>::MakeEmpty()
160 {
161     ReclaimMemory(root);
162     root = NULL;
163 }

 

 1 #include "LeftistHeap.h"
 2 
 3 
 4 int main()
 5 {
 6     LeftistHeap<int> leftistHeap1, leftistHeap2;
 7     int m, n, num;
 8     cin >> m;
 9     for (int i = 0; i < m; ++i)
10     {
11         cin >> num;
12         leftistHeap1.Insert(num);
13     }
14 
15     cin >> n;
16     for (int i = 0; i < n; ++i)
17     {
18         cin >> num;
19         leftistHeap2.Insert(num);
20     }
21 
22     leftistHeap1.Merge(leftistHeap2);
23     cout << "min num is " << leftistHeap1.FindMin() << endl;
24     if (leftistHeap1.IsEmpty())
25     {
26         cout << "leftistHeap1 is Empty!" << endl;
27     }
28     else
29     {
30         cout << "leftistHeap1 is not empty!" << endl;
31     }
32 
33     int t;
34     while (leftistHeap1.IsEmpty() == false)
35     {
36             leftistHeap1.DeleteMin(t);
37             cout << t << " ";
38     }
39         cout << endl;
40     if (leftistHeap1.IsEmpty())
41     {
42             cout << "leftistHeap1 is empty!" << endl;
43     }
44     else
45     {
46             cout << "leftistHeap1 is not empty!" << endl;
47     }
48 
49 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM