First, the basic nature
Zero path length: any node of the zero-path length NPL (X) is defined as from a to X does not have two sons nodes in the shortest path length.
Note: with zero or one son node npl is 0, the npl (nullptr) = -1.
FIG 1 zero-path length of the two trees; tree is left only the left stack of formula
Stacker left nature: for each stack node X, the zero path length of the left son, the right son is at least as long path . The figure above, namely the tree on the left to satisfy nature. This property actually exceeded its requirements to ensure that the tree unbalanced, so it is clear that the emphasis on increasing the depth of the left . There may indeed have a long path to the left node tree form constituted - so we have a name left Stacker .
Theorem: N nodes of the tree has a left formula containing up log (N + 1) th node in the right path .
Right Path: Right son of the son of the right son node right path consisting of .......
Second, the left Stacker operations:
1. merge (Merge)
The time complexity of O (log N)
DETAILED three cases (root value is set smaller than the stack H1 H2)
// merge the two root LeftistNode * Merge (* h1 of LeftistNode, LeftistNode * H2) { IF (h1 of == nullptr a) return H2; IF (H2 == nullptr a) return h1 of; IF (H1-> Element <an H2-> Element ) return merge1 (h1 of, H2); the else return merge1 (H2, h1 of); } // merge the two trees left formula h1 of <H2 LeftistNode merge1 * (* h1 of LeftistNode, LeftistNode * H2) { // single node //If left stacker h-> left = nullptr, the H-> right = nullptr a IF (H1-> left == nullptr a) h1 of > left = - ; H2 the else { // right subtree of the root node and the root recursively merged small large tree nodes H1-> right = Merge (H1-> right, H2); // zero path length is less than the left subtree right subtree exchange zero-path length of left and right subtrees IF (H1-> lEFT -> NPL <H1-> right-> NPL) swapChildren (h1 of); // root path length = zero zero path length of the right subtree. 1 + H1-> NPL = H1-> right-> NPL + . 1 ; } return h1 of; }
2. Insert (insert)
Inserting the stack as a single node with a larger stack merge.
// insert node X void INSERT ( const the Comparable & X) { the root = Merge ( new new LeftistNode {X}, the root); }
3. Delete (delete)
Delete the merger as the root of the right subtree of the left subtree and the root node, and then delete the root node.
// delete the minterm void deleteMin () { IF (isEmpty ()) the throw UnderflowException {}; LeftistNode * = OldRoot the root; the root = Merge (directory root-> left, directory root-> right); Delete OldRoot; } // delete the minimum value void deleteMin (the Comparable & minItem) { minItem = FindMin (); deleteMin (); }
Third, the code
/* * @Author: your name * @Date: 2020-02-15 16:08:15 * @LastEditTime: 2020-02-19 20:22:38 * @LastEditors: Please set LastEditors * @Description: 左式堆 * @FilePath: \LeftistHeap\Inc\LeftistHeap.h */ #ifndef __LEFTISTHEAD_H #define __LEFTISTHEAD_H #include <vector> #include <iostream> #include "dsexceptions.h" template < typename Comparable > class LeftistHeap { public: LeftistHeap( ) : root{ nullptr } { } LeftistHeap( const LeftistHeap & rhs ): root( nullptr ) { this->root = clone( rhs.root ); } ~LeftistHeap( ) { makeEmpty( ); } // 深拷贝 LeftistHeap & operator = ( const LeftistHeap & rhs ) { LeftistHeap copy = rhs; std::swap( *this, copy ); return *this; } // 移动 LeftistHeap & operator = ( LeftistHeap && rhs ) { STD :: the swap (the root, rhs.root); return * the this ; } // determines whether the stack is empty of formula left BOOL isEmpty () const { return the root == nullptr a; } // find the minimum const the Comparable & FindMin ( ) const { IF (isEmpty ()) the throw UnderflowException {}; return directory root-> Element; } // insert node X void iNSERT ( const the Comparable & X) { the root= merge( new LeftistNode{ x }, root ); } // 删除最小项 void deleteMin( ) { if( isEmpty( ) ) throw UnderflowException{ }; LeftistNode* oldRoot = root; root = merge( root->left, root->right ); delete oldRoot; } // 删除最小值 void deleteMin( Comparable & minItem ) { minItem = findMin( ); deleteMin( ); } void makeEmpty( ) { reclaimMemory (the root); the root = nullptr a; } // will be incorporated into the priority queue rhs void Merge (LeftistHeap & rhs) { IF ( the this == & rhs) // rhs must be different from the this return ; the root = Merge (the root, rhs. the root); rhs.root = nullptr a; } void Print () const { Print (the root); } Private : struct LeftistNode { the Comparable Element; LeftistNode * left; LeftistNode * right; int NPL; // zero-path length LeftistNode ( const the Comparable & E, LeftistNode lt * = nullptr a, LeftistNode * RT = nullptr a, int NP = 0 ) : Element {E}, {lt} left , right {RT}, {NP NPL} { } }; LeftistNode * the root; // root // merge the two root LeftistNode * merge (* h1 of LeftistNode, LeftistNode * H2) { IF (h1 of == nullptr a) return H2; IF (H2 == nullptr a) return h1 of; IF (H1-> Element <an H2-> Element) return merge1 (h1 of, H2); the else return merge1 (H2, h1 of); } // merge the two trees left formula h1 of <H2 LeftistNode merge1 * (* h1 of LeftistNode, LeftistNode * H2) { // single node // left stacker If h-> left = nullptr, the H-> nullptr a right = IF ( H1-> left == nullptr a) h1 of -> left = H2; the else { // recursive root combined with a small right subtree of the root node of the tree large H1-> right = Merge (H1-> right, H2); // left subtree left and right subtrees zero switching path tree length is less than a right subtree path length zero IF (H1-> lEFT -> NPL <H1-> right-> NPL) swapChildren (h1 of); // root zero path length = right subtree path length zero. 1 + H1-> NPL = H1-> right-> NPL + . 1 ; } return h1 of; } // switching node about a son void swapChildren (LeftistNode * T) { LeftistNode * = T-tempNode,> left; T->left = t->right; t->right = tempNode; } // 清空某子树 void reclaimMemory( LeftistNode* t ) { if( t != nullptr ) { reclaimMemory( t->left ); reclaimMemory( t->right ); delete t; } } // 克隆节点 LeftistNode* clone( LeftistNode* t ) const { if( t == nullptr ) return nullptr; else return new LeftistNode{ t->element, clone( t->left ), clone( t->right ), t->npl }; } void print( LeftistNode *t ) const{ if( t != nullptr ){ print( t->left ); std::cout << t->element <<" "; print( t->right ); } } }; #endif