您的位置:首页 > 理论基础 > 数据结构算法

经典数据结构之最大堆

2014-08-06 23:44 344 查看
最大堆和最小堆是常用的优先队列。 其概念也比较简单,用树的方式描述,就是,父节点比子节点大(最大堆),小则为最小堆。最大堆和最小堆广泛用在有先后顺序的任务调度中。比如cpu的任务调度等。

先上代码,后面再详细解释和补充我的看法。

头文件

#ifndef CBINARYTREE_H_INCLUDED
#define CBINARYTREE_H_INCLUDED

#include <iostream>
template<typename T>
class CMaxHeap
{
public:
CMaxHeap(int MaxSize);
CMaxHeap<T>& mInsert(const T& val);
void mPrint();
CMaxHeap<T>& mDelete(T& val);
void mInit(T vals[], const int& ArraySize, const int& MaxSize);
private:
T* m_pElems;
int m_nMaxSize;
int m_nLen;
};

template<typename T>
CMaxHeap<T>::CMaxHeap(int MaxSize) :
m_nMaxSize(MaxSize), m_nLen(0) {
m_pElems = new T[m_nMaxSize];
}

template<typename T>
CMaxHeap<T>& CMaxHeap<T>::mInsert(const T& val) {
if(m_nLen == m_nMaxSize) {
std::cerr << "the heap is full" << std::endl;
return *this;
}
T date = val;
++ m_nLen;
int cur = m_nLen; // empty pos
while(cur > 1 && m_pElems[cur / 2] < date) {
int pos = cur / 2; // left pos
if(m_pElems[pos] < m_pElems[pos + 1]) // compare left and right
++ pos;
m_pElems[cur] = m_pElems[cur / 2];
cur /= 2;
}
m_pElems[cur] = date;
return *this;
}

template<typename T>
void CMaxHeap<T>::mPrint() {
for(int i = 1; i <= m_nLen; i ++) {
std::cout << m_pElems[i] << std::endl;
}
}

template<typename T>
CMaxHeap<T>& CMaxHeap<T>::mDelete(T& data) {
if(m_nLen <= 0) {
std::cerr << "empty!!!" << std::endl;
return *this;
}
data = m_pElems[1];
T val = m_pElems[-- m_nLen];

int i = 1;
int ci = 2;
while( ci <= m_nLen) {
if(ci < m_nLen && m_pElems[ci] < m_pElems[ci + 1])
ci ++;
// if suitable
if(val > m_pElems[ci])
break;
m_pElems[i] = m_pElems[ci];
i = ci;
ci = ci * 2;
}
m_pElems[i] = val;
return *this;
}

template<typename T>
void CMaxHeap<T>::mInit(T vals[], const int& ArraySize, const int& MaxSize) {
delete [] m_pElems;
m_pElems = vals;
m_nLen = ArraySize;
m_nMaxSize = MaxSize;

for(int i = ArraySize / 2; i >= 1; i --) {
T val = m_pElems[i];
int ci = 2 * i;
// find an pos to store val;
while(ci <= m_nLen) {
if(ci < m_nLen && m_pElems[ci] < m_pElems[ci + 1])
ci ++;
if(val > m_pElems[ci])
break;
m_pElems[ci / 2] = m_pElems[ci];
ci *= 2;
}
m_pElems[ci / 2] = val;
}
}
#endif // CBINARYTREE_H_INCLUDED


测试文件

#include "CBinaryTree.h"
#include <cstdlib>
int main(int argc, char* argv[]) {
CMaxHeap<int> heap(100);
for(int i = 0; i < 10; i ++) {
heap.mInsert(rand() % 50);
}
heap.mPrint();

std::cout << "start delete" << std::endl;
for(int i = 0; i < 10; i ++) {
int val;
heap.mDelete(val);
std::cout << val << std::endl;
}

// heap2 to test Init
std::cout << "for heap 2" << std::endl;
int data[] = {1,7,4,6,2,3,10,30,17,40};
CMaxHeap<int> heap2(100);
heap2.mInit(data, sizeof(data) / sizeof(int), 40);
heap2.mPrint();
system("pause");
return 0;
}


输出结果:

14
start delete
41
34
28
24
19
17
12
8
0
0
for heap 2
40
17
30
7
3
10
6
4
2
0
其实删除的思想就是堆排序思想。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: