Priority Queue - left Stacker

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

 

Guess you like

Origin www.cnblogs.com/lsyy2020/p/12662735.html