diff --git a/thu_dsa/chp10/LeftistHeap.h b/thu_dsa/chp10/LeftistHeap.h new file mode 100644 index 0000000..8b06e1f --- /dev/null +++ b/thu_dsa/chp10/LeftistHeap.h @@ -0,0 +1,72 @@ +#ifndef LEFTISTHEAP_H_ +#define LEFTISTHEAP_H_ + +#include "PriorityQueue.h" +#include "../chp5/binTree.h" + +#define NPL(X) (X == nullptr? 0: X->npl) + +template +class LeftHeap: public PriorityQueue, public BinTree>{ +public: + //constructor + LeftHeap() = default; + LeftHeap(entry* src, int n) { for (int ix = 0; ix != n; ++ix) insert(src[ix]); } //brute force algorithm + + //public interfaces + int size() { return BinTree>::size(); } + bool empty() { return size() == 0; } + entry getMax() { return __root->data; } + entry delMax(); + void insert(entry e); + void insert(K key, V value) { insert(entry(key, value)); } +}; + +#define T entry + +template +BinNodePosi(T) merge(BinNodePosi(T) a, BinNodePosi(T) b){ + if (a == nullptr) return b; + if (b == nullptr) return a; + BinNodePosi(T) temp; + if (a->data < b->data){//swap a and b + temp = a; + a = b; + b = temp; + } + if (a->rightChild == nullptr) a->rightChild = b; + else a->rightChild = merge(a->rightChild, b); + a->rightChild->parent = a; + + if (NPL(a->leftChild) < NPL(a->rightChild)) {// swap the right chlid and left child of a + temp = a->leftChild; + a->leftChild = a->rightChild; + a->rightChild = temp; + } + a->npl = NPL(a->rightChild) + 1; + return a; +} + +//public interfaces + +template +void LeftHeap::insert(entry e){ + BinNodePosi(T) newNode = new BinNode(e); + newNode->npl = 1; + __root = merge(__root, newNode); + __root->parent = nullptr; + ++__size; +} + +template +entry LeftHeap::delMax(){ + entry res = getMax(); + __root = merge(__root->leftChild, __root->rightChild); + if (__root) __root->parent = nullptr; + --__size; + return res; +} + +#undef T + +#endif diff --git a/thu_dsa/chp10/testHeap.cpp b/thu_dsa/chp10/testHeap.cpp index 174071e..8d3ea59 100644 --- a/thu_dsa/chp10/testHeap.cpp +++ b/thu_dsa/chp10/testHeap.cpp @@ -1,4 +1,5 @@ #include "CompleteBinaryHeap.h" +#include "LeftistHeap.h" #include #include using std::cout; diff --git a/thu_dsa/chp10/testLeftHeap.cpp b/thu_dsa/chp10/testLeftHeap.cpp new file mode 100644 index 0000000..d6842c3 --- /dev/null +++ b/thu_dsa/chp10/testLeftHeap.cpp @@ -0,0 +1,59 @@ +#include "LeftistHeap.h" +#include "../chp4/Queue.h" +#include +#include +using std::cout; +using std::endl; + +void test_insert(); +void test_max(); + +int main(){ + cout << "Running tests" << endl; + + test_insert(); + test_max(); + + cout << "All tests passed." << endl; + system("pause"); + return 0; +} + +#define T entry +void test_insert(){ + int keys[] = { 5, 4, 7, 9, 1, 2, 8, 3, 6, 0 }; + int levelOrder[] = { 9, 8, 7, 2, 3, 5, 6, 1, 4, 0 }; + LeftHeap heap; + for (int ix = 0; ix != 10; ++ix) { + assert(heap.size() == ix); + heap.insert(entry(keys[ix], 0)); + } + //level-order traversal + int ix = 0; + Queue q; + BinNodePosi(T) curr; + q.enqueue(heap.root()); + while(!q.empty()){ + curr = q.dequeue(); + assert(curr->data.key == levelOrder[ix++]); + if (curr->leftChild) q.enqueue(curr->leftChild); + if (curr->rightChild) q.enqueue(curr->rightChild); + } + + cout << "test_insert passed." << endl; +} + +void test_max(){ + int keys[] = { 5, 4, 7, 9, 1, 2, 8, 3, 6, 0 }; + LeftHeap heap; + for (int ix = 0; ix != 10; ++ix) { + assert(heap.size() == ix); + heap.insert(entry(keys[ix], 0)); + } + for(int ix = 0; ix != 10; ++ix){ + assert(heap.getMax().key == 9 - ix); + assert(heap.delMax().key == 9 - ix); + assert(heap.size() == 9 - ix); + } + cout << "test_max passed." << endl; +}