堆的常用方法实现

#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     }



posted @ 2020-04-07 18:07  ponxiaoming  阅读(494)  评论(0编辑  收藏  举报