/**
这边实现的是最小堆,最小堆是这样定义的,首先堆是一棵完全二叉树,每一个节点都有一个权值,满足的条件是,父节点的权值总是大于等于子节点的权值
**/
#include <iostream>
using namespace std;
//最小堆类的定义如下
template <class T>
class MinHeap
{
private:
T * nodes; //用来存放二叉树的每一个节点的数组
int currentsize; //当前堆中有的元素个数
int maxsize; //堆中允许存放的最大的元素个数
public:
void makeHeap(int n); //建堆,创建一个空堆
MinHeap<T> & insert(T & t); //向堆中插入一个元素,保持堆得性质不变
MinHeap<T>& del(T& t); //从堆中删除最下的那个元素保持堆的性质不变,同时将这个元素放到t中
T & get(int index )
{
return nodes[index] ;
}
};
template <class T>
void MinHeap<T> ::makeHeap(int maxsize)
{
nodes = new T[maxsize+1]; //这边是一个小的技巧,开辟的一个数组的大小比最大元素个数多一个,这样堆中 //元素就是从下标1开始的,不需要进行复杂的判断了
this->maxsize = maxsize;
this->currentsize = 0;
}
/**
向堆中插入一个元素,基本的算法是这样的,首先将这个元素添加到数组的最后,然后沿着树向根方向一直查找直到这个元素应该存放的位置为止
**/
template <class T>
MinHeap<T> & MinHeap<T>::insert(T & t)
{
this ->currentsize ++;
nodes[currentsize] = t;
int index = this ->currentsize ;
while(index >1 && nodes[index] < nodes[index/2])
{
nodes [ index ] = nodes[index/2];
index = index / 2 ;
}
nodes [index ] = t;
return * this;
}
/**
删除的过程和插入的过程类似,只不过是逆过来的,从根向叶方向判断,直到找到了合适的位置。
**/
template <class T>
MinHeap<T> & MinHeap<T>::del(T&t )
{
t = nodes[1] ;
T tem = nodes[this->currentsize] ; //将最后一个元素取出来,然后放到根上 //(nodes[1])接着调整它的位置
this ->currentsize --;
int index = 1; //这个是放置tem元素的位置的下标。
int sonindex = 2; //这个变量是用来存放较小元素的子节点的下标的
while(sonindex <= this ->currentsize )
{
if(sonindex < this ->currentsize && nodes[sonindex] > nodes[sonindex+1]) //这边是找出index元素的两个子节点中值较小 //的那个
sonindex ++;
if(tem < nodes[sonindex])
break;
nodes[index] = nodes[sonindex];
index = sonindex;
sonindex *= 2;
}
nodes [index] = tem;
return * this;
}
int main()
{
MinHeap<int> heap ;
heap.makeHeap(10);
for(int i =0 ;i < 6; i ++)
heap.insert(i);
for(int i = 1;i <= 6 ;i ++)
cout << heap.get(i) << " " ;
cout << endl;
for(int i = 0 ;i < 6;i ++)
{
int x;
heap.del(x);
cout << x << endl;
}
return 0 ;
}