左式堆

Posted 张宇航

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了左式堆相关的知识,希望对你有一定的参考价值。

零路径长:从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 }
技术分享

以上是关于左式堆的主要内容,如果未能解决你的问题,请参考以下文章

左式堆

左式堆的实现与详解

转载:数据结构 左式堆

堆之左式堆和斜堆

左式堆的合并

左式堆