博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

堆的C++代码实现

Posted on 2011-05-15 18:16  各种不会  阅读(573)  评论(0)    收藏  举报

其实堆这个概念很早就知道了,也大概能说出来它的用途,但是真要是让用代码去实现的话,就没有看起来那么简单了,切忌不可眼高手低。

堆的基本操作:插入一个元素,删除最大的元素也就是根节点,其他堆调整操作都是为这两个操作服务的。堆分为最大堆和最小堆,这里实现一个最大堆。还有就是一个在建堆的时候很有用的性质:一个大小为N的堆,其叶子节点的下标是N/2+1,N/2+2.......n. 这样就可以少循环N/2次,因为叶子节点本身就是最大堆,不需要调整。

1 template<class T> class MaxHeap{
2  private:
3 T *datas;
4 int MaxSize;
5 int currentSize;
6 void KeepHeap(int root);
7 bool del;
8  public:
9 MaxHeap(int MaxSize);
10 MaxHeap(T *datas, int length);
11 ~MaxHeap();
12 bool Insert(T data);
13 T GetMax();
14 void RemoveMax();
15 void PrintHeap(){
16 for (int i=1; i<=currentSize; i++)
17 {
18 cout << datas[i] << " ";
19 }
20 cout << endl;
21 }
22 int GetCurrentSize()
23 {
24 return currentSize;
25 }
26 //void BuildMaxHeap(T *datas);
27  };
28
29 template <class T> MaxHeap<T>::MaxHeap(T *datas, int length)
30 {
31 this->datas = datas;
32 currentSize = length;
33 MaxSize = currentSize;
34 for (int i=currentSize/2; i>0; i--)
35 {
36 KeepHeap(i);
37 }
38 del = false;
39 }
40
41 template<class T> MaxHeap<T>::MaxHeap(int MaxSize)
42 {
43 this->MaxSize = MaxSize;
44 datas = new T[this->MaxSize+1];
45 this->currentSize = 0;
46 del = true;
47 }
48
49 template<class T> MaxHeap<T>::~MaxHeap()
50 {
51 if(del)
52 delete []datas;
53 }
54
55 template<class T> bool MaxHeap<T>::Insert(T data)
56 {
57 if (currentSize+1 > MaxSize)
58 {
59 return false;
60 }
61 datas[++currentSize] = data;
62 int index = currentSize;
63 int temp = (index)/2;
64 while (temp>=1)
65 {
66 if (datas[temp]<data)
67 {
68 datas[index] = datas[temp];
69 index = temp;
70 temp = temp/2;
71 }else{
72 break;
73 }
74 }
75 datas[index] = data;
76 return true;
77 }
78
79 template<class T> T MaxHeap<T>::GetMax()
80 {
81 return datas[1];
82 }
83
84 template<class T> void MaxHeap<T>::KeepHeap(int root)
85 {
86 int temp = datas[root];
87 while (root*2<=currentSize)
88 {
89 int child = root*2;
90 if (child+1<=currentSize && datas[child] < datas[child+1])
91 {
92 child++;
93 }
94 if (temp > datas[child])
95 {
96 break;
97 }else
98 {
99 datas[root] = datas[child];
100 }
101 root = child;
102 }
103 datas[root] = temp;
104 }
105
106 template<class T> void MaxHeap<T>::RemoveMax()
107 {
108 int temp = datas[1];
109 datas[1] = datas[currentSize];
110 datas[currentSize] = temp;
111 currentSize--;
112 KeepHeap(1);
113 }

堆的使用:堆最直接的使用就是用来排序;还有就是找当K比较小能放进内存的时候,用来找前K个最小数(用最大堆)或者K个最大数(用最大堆)

1 #include "stdafx.h"
2 #include <iostream>
3 #include "MaxHeap.h"
4
5  using namespace std;
6 class A{
7 public:
8 A(int *data, int len){}
9 };
10
11 void MinK(int *data, int length, int k)
12 {
13 MaxHeap<int> heap(length);
14 for (int i=1; i<length; i++)
15 {
16 if (k>heap.GetCurrentSize())
17 {
18 heap.Insert(data[i]);
19 }else{
20 if (data[i]<heap.GetMax())
21 {
22 heap.RemoveMax();
23 heap.Insert(data[i]);
24 }
25 }
26 }
27 heap.PrintHeap();
28 }
29
30 int main(int argc, char* argv[])
31 {
32 // MaxHeap<int> h(4);
33 // h.Insert(1);
34 // h.Insert(2);
35 // h.Insert(3);
36 int data[] = {-1,15,24,3,8,7,6,5,7};
37 int len = sizeof(data)/sizeof(int);
38 MaxHeap<int> h(data, len-1);
39 for (int i=1; i<len; i++)
40 {
41 h.RemoveMax();
42 }
43 for (i=1; i<len; i++)
44 cout << data[i] << " ";
45 cout << endl;
46
47 MinK(data,len,3);
48 return 0;
49 }