左式堆
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 }
以上是关于左式堆的主要内容,如果未能解决你的问题,请参考以下文章