/**
這邊實現的是最小堆,最小堆是這樣定義的,首先堆是一棵完全二叉樹,每一個節點都有一個權值,滿足的條件是,父節點的權值總是大於等於子節點的權值
**/
#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 ;
}