zoukankan      html  css  js  c++  java
  • 左式堆

    零路径长:从X到一个不具有两个儿子的结点的最短路径的长。

    性质:

    任一结点的零路径长比他的诸儿子结点的零路径长的最小值多1

    父节点属性值小于子节点属性值;

    堆中的任何节点,其左儿子的零路径长>=右儿子的零路径长;的二叉树。

    下面是左式堆的类型声明:

     1 template <typename Comparable>
     2 class LeftistHeap
     3 {
     4 public:
     5     LeftistHeap();
     6     LeftistHeap(const LeftistHeap & rhs);
     7     ~LeftistHeap();
     8 
     9     bool isEmpty() const;
    10     const Comparable & findMin() const;
    11 
    12     void insert(const Comparable & x);
    13     void deleteMin();
    14     void deleteMin(Comparable & minItem);
    15     void makeEmpty();
    16     void merge(LeftistHeap & rhs);
    17 
    18     const LeftistHeap & operator=(const LeftistHeap & rhs);
    19 
    20 private:
    21     struct LeftistNode
    22     {
    23         Comparable element;
    24         LeftistNode *left;
    25         LeftistNode *right;
    26         int npl;
    27 
    28         LeftistNode(const Comparable & theElement,LeftistNode *lt = NULL,LeftistNode *rt = NULL,int np=0)
    29             :element(theElement),left(lt),right(rt),npl(np)
    30         {
    31         }
    32     };
    33     LeftistNode *root;
    34     LeftistNode * merge(LeftistHeap *h1,LeftistHeap *h2);
    35     LeftistNode * merge1(LeftistHeap *h1,LeftistHeap *h2);
    36 
    37     void swapChildren(LeftistHeap *t);
    38     void reclaimMemory(LeftistHeap *t);
    39     LeftistNode * clone(LeftistHeap *t) const;
    40 }

    合并左式堆的驱动实例:

    void merge(LeftistHeap & rhs)
    {
        if(this == &rhs)
            return;
        root = merge(root,rhs.root );
        rhs.root = NULL;
    }
    LeftistNode * merge(LeftistNode * h1,LeftistNode *h2)
    {
        if(h1 == NULL)
            return h2;
        if(h2 == NULL)
            return h1;
        if(h1->element < h2->element)
            return mergel(h1,h2);
        else
            return mergel(h2,h1);
    }

    合并左式堆的实例:

     1 LeftistNode * mergel(LeftistNode *h1,LeftistNode *h2)
     2 {
     3     if(h1->left == NULL)
     4         h1->left = h2;
     5     else
     6     {
     7         h1->right = merge(h1->right,h2);
     8         if(h1->left->npl < h1->right->npl)
     9             swapChildren(h1);
    10         h1->npl = h1->right->npl + 1;
    11     }
    12     return h1;
    13 }

    左式堆的插入操作:

    1 void insert(const Comparable & x)
    2 {
    3     root = merge(new LeftListNode(x),root);
    4 }

    左式堆的deleteMin操作:

     1  void deleteMin()
     2  {
     3      if(isEmpty())
     4          throw UnderflowException();
     5      LeftistNode * oldRoot = root;
     6      root = merge(root->left,root->right);
     7      delete oldRoot;
     8  }
     9  void deleteMin(Comparable & minItem)
    10  {
    11     minItem = findMin();
    12     deleteMin();
    13  }

    下面是左式堆的应用实例:

      1 #ifndef LeftistHeap_h__
      2 #define LeftistHeap_h__
      3 #define    NULL    0
      4 // ******************公共操作*********************
      5 // void insert( x )       --> 插入x
      6 // deleteMin( minItem )   --> 删除最小元素
      7 // Comparable findMin( )  --> 返回最小元素
      8 // bool isEmpty( )        --> 为空返回true,否则返回false
      9 // void makeEmpty( )      --> 清空
     10 // void merge( rhs )      --> 合并rhs到本堆中
     11 // ******************说明********************************
     12 //    代码根据数据结构与算法分析中的代码编写
     13 template <typename Comparable>
     14 class LeftistHeap
     15 {
     16 public:
     17     LeftistHeap():root(NULL)
     18     {}
     19     LeftistHeap(const LeftistHeap &rhs)
     20     {
     21         *this = rhs;
     22     }
     23     ~LeftistHeap()
     24     {
     25         makeEmtpy();
     26     }
     27     //插入x元素
     28     void insert(const Comparable &x)
     29     {
     30         root = merge(new LeftistNode(x), root);
     31     };
     32     //为空返回true,否则返回false
     33     bool isEmpty() const
     34     {
     35         return root == NULL;
     36     }
     37     //找到最小元素并返回其值
     38     const Comparable& findMin() const
     39     {
     40         if(!isEmpty())
     41             return root->element;
     42     }
     43     //删除最小元素
     44     void deleteMin()
     45     {
     46         if(isEmpty())
     47             return;
     48         LeftistNode* oldroot = root;
     49         root = merge(root->left, root->right);
     50         delete oldroot;
     51     }
     52     //删除最小元素,并将其值赋予minItem
     53     void deleteMin(Comparable &minItem)
     54     {
     55         minItem = findMin();
     56         deleteMin();
     57     }
     58     //清空
     59     void makeEmtpy()
     60     {
     61         reclaimMemory(root);
     62         root = NULL;
     63     }
     64     //将另一个堆合并到本堆中
     65     void merge(LeftistHeap &rhs)
     66     {
     67         if(this == &rhs)
     68             return;
     69         root = merge(root, rhs.root);
     70         rhs.root = NULL;
     71     }
     72     const LeftistHeap& operator=(const LeftistHeap &rhs)
     73     {
     74         if(this != &rhs)
     75         {
     76             makeEmtpy();
     77             root = clone(rhs.root);
     78         }
     79         return *this;
     80     }
     81 private:
     82     struct LeftistNode
     83     {
     84         Comparable    element;
     85         LeftistNode    *left;
     86         LeftistNode    *right;
     87         int            npl;
     88         LeftistNode(const Comparable &e, LeftistNode *l = NULL,
     89             LeftistNode *r = NULL, int n = 0)
     90             :element(e), left(l), right(r), npl(n)
     91         {}
     92     };
     93     LeftistNode *root;
     94     //处理非一般情况,并递归调用merge1
     95     LeftistNode* merge(LeftistNode *h1, LeftistNode *h2)
     96     {
     97         if(h1 == NULL)
     98             return h2;
     99         if(h2 == NULL)
    100             return h1;
    101         if(h1->element < h2->element)
    102             merge1(h1, h2);
    103         else
    104             merge1(h2, h1);
    105     }
    106     //合并两个节点
    107     //h1是具有最小元素的根节点
    108     LeftistNode* merge1(LeftistNode *h1, LeftistNode *h2)
    109     {
    110         if(h1->left == NULL)
    111             h1->left = h2;
    112         else
    113         {
    114             h1->right = merge(h1->right, h2);
    115             if(h1->left->npl < h1->right->npl)
    116                 swapChildren(h1);
    117             h1->npl = h1->right->npl + 1;
    118         }
    119         return h1;
    120     }
    121     void swapChildren(LeftistNode *t)
    122     {
    123         LeftistNode *tmp = t->left;
    124         t->left = t->right;
    125         t->right = tmp;
    126     }
    127     void reclaimMemory(LeftistNode *t)
    128     {
    129         if(t != NULL)
    130         {
    131             reclaimMemory(t->left);
    132             reclaimMemory(t->right);
    133             delete t;
    134         }
    135     }
    136     LeftistNode *clone(LeftistNode *t) const
    137     {
    138         if(t == NULL)
    139             return NULL;
    140         else
    141             return new LeftistNode(t->element, clone(t->left), clone(t->right));
    142     }
    143 };
    144 #endif // LeftistHeap_h__
     1 #include "LeftistHeap.h"
     2 #include <cstdlib>
     3 #include <ctime>
     4 #include <iostream>
     5 using namespace std;
     6 int main()
     7 {
     8     LeftistHeap<int> leftistHeapA, leftistHeapB, leftistHeapC;
     9     srand((unsigned)time(0));  
    10     for(int i=0; i< 1000; i++)  
    11     {  
    12         int t = rand();   
    13         leftistHeapA.insert(t);
    14     }
    15     for(int i=0; i< 1000; i++)  
    16     {  
    17         int t = rand();   
    18         leftistHeapB.insert(t);
    19     }
    20     leftistHeapA.merge(leftistHeapB);
    21     leftistHeapA.merge(leftistHeapC);
    22     int t;
    23     while(leftistHeapA.isEmpty() == false)
    24     {
    25         leftistHeapA.deleteMin(t);
    26         cout<<t<<" ";
    27     }
    28     cout<<endl;
    29     getchar();
    30     return 0;
    31 }
  • 相关阅读:
    浅析 x1B[1;3;31mxterm.jsx1B[0m 是什么?如何在终端输出带颜色等格式的字符串
    使用xterm报错:Error: Terminal requires a parent element、及删除时报错:xterm.js: Parsing error 的问题
    浅析如何实现浏览器访问远程桌面/服务器界面:NoVNC
    浅析NAS网络存储是什么及其主要用途
    浅析uniapp如何做图片裁剪及遇到问题 uni.canvasToTempFilePath 在APP下返回的是临时路径,如何把路径转为base64的解决方案
    浅析webpack中mode的取值及不同取值的作用/打包方式及摇树优化(tree-shaking)的理解
    P1160 队列安排题解
    P1996 约瑟夫问题题解
    P1449 后缀表达式题解
    P1825 玉米田迷宫题解
  • 原文地址:https://www.cnblogs.com/xing901022/p/2699001.html
Copyright © 2011-2022 走看看