左式堆是堆的一种,非常适合合并。 合并的递归定义是:递归的将具有大的根值的堆与具有小的根值的堆的右子树合并,并保持堆的基本性质。 LeftistHeap.h #ifndef LeftistHeap_h__ #define LeftistHeap_h__ #define NULL 0 // ******************公共操作********************* // void insert( x ) --> 插入x // deleteMin( minItem ) --> 删除最小元素 // Comparable findMin( ) --> 返回最小元素 // bool isEmpty( ) --> 为空返回true,否则返回false // void makeEmpty( ) --> 清空 // void merge( rhs ) --> 合并rhs到本堆中 // ******************说明******************************** // 代码根据数据结构与算法分析中的代码编写 template <typename Comparable> class LeftistHeap { public: LeftistHeap():root(NULL) {} LeftistHeap(const LeftistHeap &rhs) { *this = rhs; } ~LeftistHeap() { makeEmtpy(); } //插入x元素 void insert(const Comparable &x) { root = merge(new LeftistNode(x), root); }; //为空返回true,否则返回false bool isEmpty() const { return root == NULL; } //找到最小元素并返回其值 const Comparable& findMin() const { if(!isEmpty()) return root->element; } //删除最小元素 void deleteMin() { if(isEmpty()) return; LeftistNode* oldroot = root; root = merge(root->left, root->right); delete oldroot; } //删除最小元素,并将其值赋予minItem void deleteMin(Comparable &minItem) { minItem = findMin(); deleteMin(); } //清空 void makeEmtpy() { reclaimMemory(root); root = NULL; } //将另一个堆合并到本堆中 void merge(LeftistHeap &rhs) { if(this == &rhs) return; root = merge(root, rhs.root); rhs.root = NULL; } const LeftistHeap& operator=(const LeftistHeap &rhs) { if(this != &rhs) { makeEmtpy(); root = clone(rhs.root); } return *this; } private: struct LeftistNode { Comparable element; LeftistNode *left; LeftistNode *right; int npl; LeftistNode(const Comparable &e, LeftistNode *l = NULL, LeftistNode *r = NULL, int n = 0) :element(e), left(l), right(r), npl(n) {} }; LeftistNode *root; //处理非一般情况,并递归调用merge1 LeftistNode* merge(LeftistNode *h1, LeftistNode *h2) { if(h1 == NULL) return h2; if(h2 == NULL) return h1; if(h1->element < h2->element) merge1(h1, h2); else merge1(h2, h1); } //合并两个节点 //h1是具有最小元素的根节点 LeftistNode* merge1(LeftistNode *h1, LeftistNode *h2) { if(h1->left == NULL) h1->left = h2; else { h1->right = merge(h1->right, h2); if(h1->left->npl < h1->right->npl) swapChildren(h1); h1->npl = h1->right->npl + 1; } return h1; } void swapChildren(LeftistNode *t) { LeftistNode *tmp = t->left; t->left = t->right; t->right = tmp; } void reclaimMemory(LeftistNode *t) { if(t != NULL) { reclaimMemory(t->left); reclaimMemory(t->right); delete t; } } LeftistNode *clone(LeftistNode *t) const { if(t == NULL) return NULL; else return new LeftistNode(t->element, clone(t->left), clone(t->right)); } }; #endif // LeftistHeap_h__ 测试代码: #include "LeftistHeap.h" #include <cstdlib> #include <ctime> #include <iostream> using namespace std; int main() { LeftistHeap<int> leftistHeapA, leftistHeapB, leftistHeapC; srand((unsigned)time(0)); for(int i=0; i< 1000; i++) { int t = rand(); leftistHeapA.insert(t); } for(int i=0; i< 1000; i++) { int t = rand(); leftistHeapB.insert(t); } leftistHeapA.merge(leftistHeapB); leftistHeapA.merge(leftistHeapC); int t; while(leftistHeapA.isEmpty() == false) { leftistHeapA.deleteMin(t); cout<<t<<" "; } cout<<endl; getchar(); return 0; }