• 堆的常用方法实现


    #include<algorithm>

    常用方法有4个:make_heap、sort_heap、pop_heap、push_heap

    这4个函数的参数都一样,返回值都为void。

    first  首元素地址

    last  尾元素地址

    cmp  比较函数(决定大堆还是小堆)

      1 template <class T>
      2 class MinHeap
      3 {
      4 private:
      5     T *heapArray;
      6     int CurrentSize;
      7     int MaxSize;
      8     void BuildHeap(); // 最小堆ADT定义
      9     // 存放堆数据的数组 // 当前堆中元素数目
     10     // 堆所能容纳的最大元素数目 // 建堆
     11 public:
     12     MinHeap(const int n); // 构造函数,n为最大元素数目
     13     virtual ~MinHeap()
     14     {
     15         delete[] heapArray;
     16     };
     17     bool isLeaf(int pos) const;
     18     int leftchild(int pos) const;
     19     int rightchild(int pos) const;
     20     int parent(int pos) const;
     21     // 返回左孩子位置 // 返回右孩子位置 // 返回父结点位置
     22     bool Remove(int pos, T &node); // 删除给定下标元素
     23     bool Insert(const T &newNode); //向堆中插入新元素
     24     T &RemoveMin();
     25     // 从堆顶删除最小值
     26     void SiftUp(int position); // 从position向上调整堆
     27     void SiftDown(int left);
     28 };
     29 template <class T>
     30 MinHeap<T>::MinHeap(const int n)
     31 {
     32     if (n <= 0)
     33         return;
     34     CurrentSize = 0;
     35     MaxSize = n;
     36     heapArray = new T[MaxSize];
     37     BuildHeap();
     38 }
     39 template <class T>
     40 //初始化堆容量为n //创建堆空间
     41 //此处进行堆元素的赋值工作
     42 //判断是否叶结点
     43 bool MinHeap<T>::isLeaf(int pos) const
     44 {
     45     return (pos >= CurrentSize / 2) && (pos < CurrentSize);
     46 }
     47 template <class T>
     48 int MinHeap<T>::leftchild(int pos) const
     49 {
     50     return 2 * pos + 1;
     51 }
     52 template <class T>
     53 int MinHeap<T>::rightchild(int pos) const
     54 {
     55     return 2 * pos + 2;
     56 }
     57 template <class T>
     58 //返回当前结点的父结点位置
     59 int MinHeap<T>::parent(int pos) const
     60 {
     61     return (pos - 1) / 2;
     62     //DIV //返回右孩子位置
     63 }
     64 template <class T>
     65 void MinHeap<T>::SiftDown(int position)
     66 {
     67     int i = position;
     68     int j = 2 * i + 1;
     69     T temp = heapArray[i];
     70     while (j < CurrentSize)
     71     {
     72         //标识父结点
     73         //标识关键值较小的子结点 //保存父结点 //过筛
     74         if ((j < CurrentSize - 1) && (heapArray[j] > heapArray[j + 1]))
     75             j++;
     76         //j指向数值较小的子结点
     77         if (heapArray[j] < temp)
     78         {
     79             heapArray[i] = heapArray[j];
     80             i = j;
     81             j = 2 * j + 1;
     82         }
     83         else
     84             break;
     85     }
     86     heapArray[i] = temp;
     87 }
     88 template <class T>
     89 void MinHeap<T>::BuildHeap()
     90 {
     91     for (int i = CurrentSize / 2 - 1; i >= 0; i--)
     92         SiftDown(i);
     93     //反复调用筛选函数
     94 }
     95 template <class T> //向堆中插入新元素
     96 bool MinHeap<T>::Insert(const T &newNode)
     97 {
     98     if (CurrentSize == MaxSize)
     99         return false;
    100     //堆空间已经满
    101     heapArray[CurrentSize] = newNode;
    102     SiftUp(CurrentSize);
    103     CurrentSize++;
    104 }
    105 template <class T> //从position向上开始调整,使序列成为堆
    106 void MinHeap<T>::SiftUp(int position)
    107 {
    108     int temppos = position;
    109     T temp = heapArray[temppos]; //请比较父子结点直接swap的方法
    110     while ((temppos > 0) && (heapArray[parent(temppos)] > temp))
    111     {
    112         heapArray[temppos] = heapArray[parent(temppos)];
    113         temppos = parent(temppos);
    114     }
    115     heapArray[temppos] = temp;
    116 }
    117 
    118 template <T>
    119 T &MinHeap<T>::RemoveMin()
    120 { //从堆顶删除最小值
    121     if (CurrentSize == 0)
    122     {
    123         //空堆
    124         cout << "Can't Delete";
    125         exit(1);
    126     }
    127     else
    128     {
    129         swap(0, --CurrentSize);
    130         if (CurrentSize > 1)
    131             SiftDown(0);
    132         return heapArray[CurrentSize];
    133     }
    134 }
    135 //交换堆顶和最后一个元素 // <=1就不要调整了 //从堆顶开始筛选
    136 
    137 template <class T>
    138 bool MinHeap<T>::Remove(int pos, T &node)
    139 {
    140     if ((pos < 0) || (pos >= CurrentSize))
    141         return false;
    142     T temp = heapArray[pos];
    143     heapArray[pos] = heapArray[--CurrentSize];
    144     SiftUp(pos);
    145     SiftDown(pos);
    146     node = temp;
    147     return true;
    148 }
    149 
    150 template <class T>
    151 class HuffmanTree
    152 {
    153 private:
    154     HuffmanTreeNode<T> *root;
    155     //Huffman树的树根
    156     //把ht1和ht2为根的合并成一棵以parent为根的Huffman子树
    157     void MergeTree(HuffmanTreeNode<T> &ht1, HuffmanTreeNode<T> &ht2, HuffmanTreeNode<T> *parent);
    158 
    159 public: //构造Huffman树,weight是存储权值的数组,n是数组长度
    160     HuffmanTree(T weight[], int n);
    161     virtual ~HuffmanTree()
    162     {
    163         DeleteTree(root);
    164     } //析构函数
    165 };
    166 template <class T>
    167 HuffmanTree<T>::HuffmanTree(T weight[], int n)
    168 {
    169     MinHeap<HuffmanTreeNode<T>> heap;
    170     //定义最小值堆
    171     HuffmanTreeNode<T> *parent, &leftchild, &rightchild;
    172     HuffmanTreeNode<T> *NodeList = new HuffmanTreeNode<T>[n];
    173     for (int i = 0; i < n; i++)
    174     {
    175         NodeList[i].element = weight[i];
    176         NodeList[i].parent = NodeList[i].left = NodeList[i].right = NULL;
    177         heap.Insert(NodeList[i]);
    178     } //end for
    179     for (i = 0; i < n - 1; i++)
    180     { //通过n-1次合并建立Huffman树
    181         parent = new HuffmanTreeNode<T>;
    182         firstchild = heap.RemoveMin();
    183         secondchild = heap.RemoveMin();
    184         //选值最小的结点 //选值次小的结点
    185         MergeTree(firstchild, secondchild, parent); //权值最小树合并
    186         heap.Insert(*parent);
    187         root = parent;
    188         //把parent插入到堆中去 //建立根结点
    189     } //end for
    190     delete[] NodeList;
    191     }



  • 相关阅读:
    ASP.Net 反射显示
    ASP.Net 反射简单工厂模式
    ASP.Net MVC生成验证码
    ASP.Net EF架构
    ASP.Net 邮箱发送
    ASP.Net 反射简单
    ASP.Net 显示
    新年快乐
    测试开发比
    Linkbot介绍
  • 原文地址:https://www.cnblogs.com/ponxiaoming/p/12654948.html
Copyright © 2020-2023  润新知