zoukankan      html  css  js  c++  java
  • 数据结构-左式堆

    复杂度:

    实现:

      1 #ifndef LEFTIST_HEAP_H
      2 #define LEFTIST_HEAP_H
      3 
      4 #include "dsexceptions.h"
      5 #include <iostream>
      6 using namespace std;
      7 
      8 // Leftist heap class
      9 //
     10 // CONSTRUCTION: with no parameters
     11 //
     12 // ******************PUBLIC OPERATIONS*********************
     13 // void insert( x )       --> Insert x
     14 // deleteMin( minItem )   --> Remove (and optionally return) smallest item
     15 // Comparable findMin( )  --> Return smallest item
     16 // bool isEmpty( )        --> Return true if empty; else false
     17 // void makeEmpty( )      --> Remove all items
     18 // void merge( rhs )      --> Absorb rhs into this heap
     19 // ******************ERRORS********************************
     20 // Throws UnderflowException as warranted
     21 
     22 template <typename Comparable>
     23 class LeftistHeap
     24 {
     25   public:
     26     LeftistHeap( ) : root{ nullptr }
     27       { }
     28     LeftistHeap( const LeftistHeap & rhs ) : root{ nullptr }
     29       { root = clone( rhs.root ); }
     30     
     31     LeftistHeap( LeftistHeap && rhs ) : root{ rhs.root }
     32     {
     33         rhs.root = nullptr;
     34     }
     35     
     36     ~LeftistHeap( )
     37       { makeEmpty( ); }
     38     
     39     
     40     /**
     41      * Deep copy.
     42      */
     43     LeftistHeap & operator=( const LeftistHeap & rhs )
     44     {
     45         LeftistHeap copy = rhs;
     46         std::swap( *this, copy );
     47         return *this;
     48     }
     49         
     50     /**
     51      * Move.
     52      */
     53     LeftistHeap & operator=( LeftistHeap && rhs )
     54     {
     55         std::swap( root, rhs.root );
     56         
     57         return *this;
     58     }
     59     
     60     /**
     61      * Returns true if empty, false otherwise.
     62      */
     63     bool isEmpty( ) const
     64       { return root == nullptr; }
     65     
     66     /**
     67      * Find the smallest item in the priority queue.
     68      * Return the smallest item, or throw Underflow if empty.
     69      */
     70     const Comparable & findMin( ) const
     71     {
     72         if( isEmpty( ) )
     73             throw UnderflowException{ };
     74         return root->element;
     75     }
     76 
     77     /**
     78      * Inserts x; duplicates allowed.
     79      */
     80     void insert( const Comparable & x )
     81       { root = merge( new LeftistNode{ x }, root ); }
     82 
     83     /**
     84      * Inserts x; duplicates allowed.
     85      */
     86     void insert( Comparable && x )
     87       { root = merge( new LeftistNode{ std::move( x ) }, root ); }
     88 
     89     /**
     90      * Remove the minimum item.
     91      * Throws UnderflowException if empty.
     92      */
     93     void deleteMin( )
     94     {
     95         if( isEmpty( ) )
     96             throw UnderflowException{ };
     97 
     98         LeftistNode *oldRoot = root;
     99         root = merge( root->left, root->right );
    100         delete oldRoot;
    101     }
    102 
    103     /**
    104      * Remove the minimum item and place it in minItem.
    105      * Throws UnderflowException if empty.
    106      */
    107     void deleteMin( Comparable & minItem )
    108     {
    109         minItem = findMin( );
    110         deleteMin( );
    111     }
    112 
    113     /**
    114      * Make the priority queue logically empty.
    115      */
    116     void makeEmpty( )
    117     {
    118         reclaimMemory( root );
    119         root = nullptr;
    120     }
    121 
    122     /**
    123      * Merge rhs into the priority queue.
    124      * rhs becomes empty. rhs must be different from this.
    125      */
    126     void merge( LeftistHeap & rhs )
    127     {
    128         if( this == &rhs )    // Avoid aliasing problems
    129             return;
    130 
    131         root = merge( root, rhs.root );
    132         rhs.root = nullptr;
    133     }
    134 
    135 
    136   private:
    137     struct LeftistNode
    138     {
    139         Comparable   element;
    140         LeftistNode *left;
    141         LeftistNode *right;
    142         int          npl;
    143 
    144         LeftistNode( const Comparable & e, LeftistNode *lt = nullptr,
    145                         LeftistNode *rt = nullptr, int np = 0 )
    146           : element{ e }, left{ lt }, right{ rt }, npl{ np } { }
    147         
    148         LeftistNode( Comparable && e, LeftistNode *lt = nullptr,
    149                         LeftistNode *rt = nullptr, int np = 0 )
    150           : element{ std::move( e ) }, left{ lt }, right{ rt }, npl{ np } { }
    151     };
    152 
    153     LeftistNode *root;
    154 
    155     /**
    156      * Internal method to merge two roots.
    157      * Deals with deviant cases and calls recursive merge1.
    158      */
    159     LeftistNode * merge( LeftistNode *h1, LeftistNode *h2 )
    160     {
    161         if( h1 == nullptr )
    162             return h2;
    163         if( h2 == nullptr )
    164             return h1;
    165         if( h1->element < h2->element )
    166             return merge1( h1, h2 );
    167         else
    168             return merge1( h2, h1 );
    169     }
    170 
    171     /**
    172      * Internal method to merge two roots.
    173      * Assumes trees are not empty, and h1's root contains smallest item.
    174      */
    175     LeftistNode * merge1( LeftistNode *h1, LeftistNode *h2 )
    176     {
    177         if( h1->left == nullptr )   // Single node
    178             h1->left = h2;       // Other fields in h1 already accurate
    179         else
    180         {
    181             h1->right = merge( h1->right, h2 );
    182             if( h1->left->npl < h1->right->npl )
    183                 swapChildren( h1 );
    184             h1->npl = h1->right->npl + 1;
    185         }
    186         return h1;
    187     }
    188 
    189     /**
    190      * Swaps t's two children.
    191      */
    192     void swapChildren( LeftistNode *t )
    193     {
    194         LeftistNode *tmp = t->left;
    195         t->left = t->right;
    196         t->right = tmp;
    197     }
    198 
    199     /**
    200      * Internal method to make the tree empty.
    201      * WARNING: This is prone to running out of stack space;
    202      *          exercises suggest a solution.
    203      */
    204     void reclaimMemory( LeftistNode *t )
    205     {
    206         if( t != nullptr )
    207         {
    208             reclaimMemory( t->left );
    209             reclaimMemory( t->right );
    210             delete t;
    211         }
    212     }
    213     
    214     /**
    215      * Internal method to clone subtree.
    216      * WARNING: This is prone to running out of stack space.
    217      *          exercises suggest a solution.
    218      */
    219     LeftistNode * clone( LeftistNode *t ) const
    220     {
    221         if( t == nullptr )
    222             return nullptr;
    223         else
    224             return new LeftistNode{ t->element, clone( t->left ), clone( t->right ), t->npl };
    225     }
    226 };
    227 
    228 #endif

    应用:

     1 #include "LeftistHeap.h"
     2 #include <iostream>
     3 using namespace std;
     4 
     5 int main( )
     6 {
     7     int numItems = 10000;
     8     LeftistHeap<int> h;
     9     LeftistHeap<int> h1;
    10     LeftistHeap<int> h2;
    11     int i = 37;
    12 
    13     cout << "Begin test..." << endl;
    14     for( i = 37; i != 0; i = ( i + 37 ) % numItems )
    15         if( i % 2 == 0 )
    16             h1.insert( i );
    17         else
    18             h.insert( i );
    19     h.merge( h1 );
    20     h2 = h;
    21 
    22     for( i = 1; i < numItems; ++i )
    23     {
    24         int x;
    25         h2.deleteMin( x );
    26         if( x != i )
    27             cout << "Oops! " << i << endl;
    28     }
    29 
    30     if( !h1.isEmpty( ) )
    31         cout << "Oops! h1 should have been empty!" << endl;
    32 
    33     cout << "End test... no other output is good" << endl;
    34 
    35     return 0;
    36 }
  • 相关阅读:
    Python之路第一课Day1--随堂笔记
    前端面试题汇总
    全国计算机二级python备考
    小程序体检评分优化
    自己配置webpack报错总结
    npm install 报错npm WARN tar ENOENT: no such file or directory和npm ERR! cb() never called!可能的原因
    vue 里面使用sass进行代码复用mixin简单用法
    用openlayers初始化地图碰到过的 地图不显示的问题 VUE
    element el-table表格树状图全选/取消 子节点无法选中问题
    element 树形结构自定义节点图标
  • 原文地址:https://www.cnblogs.com/dracohan/p/3879849.html
Copyright © 2011-2022 走看看