最小堆的構建(C++實現)--演算法拾遺(1)
阿新 • • 發佈:2019-02-04
現在開始想把平時遇到的零星的演算法都記錄在這個板塊裡,因為若是沒有平常的記錄而只是將曾經實現過的程式碼爛在資料夾裡的話確實不是一個很好的做法啊。畢竟這是筆記而非展示給那個平臺下的報告,所以有的時候寫的隨便一點。有時演算法具體實現上的參考出處我也會做上註釋。
今天開始實現一個最小堆,演算法較為簡單功能不算完善。我參考了 C++實現堆、最大堆、最小堆 – 堆排序插入刪除操作 這個部落格的程式碼。先直接貼上程式碼吧。
#include<iostream>
using namespace std;
template<class T>
class Heap
{
public :
void show_heap();
void Push(T value);
T Pop();
Heap():_size(0),_capicity(10){}
Heap(T* data ,int size);
~Heap(){}
protected:
void shift_up(int cursor);
void shift_down(int start,int end);
private:
T* heap;
int _capicity;
int _size;
};
template<class T>
Heap<T>::Heap(T* data ,int size)
{
this->_size=size;
heap=new T[size];
for(int i=0;i<size;i++)
heap[i]=data[i];
for(int i=size/2-1;i>=0;i--){
shift_down(i,_size-1);
}
}
template<class T>
void Heap<T>::Push(T values)
{
if(_size>=_capicity)
return ;
heap[_size]=values;
shift_up(_size);
_size++;
}
template <class T>
T Heap<T>::Pop()
{
if(_size==0)
return ;
T result=heap[0];
heap[0]=heap[_size-1];
_size--;
shift_down(0,_size-1);
}
template<class T>
void Heap<T>::shift_down(int start,int end) //下濾
{
int i=start;
int j=i*2+1;
T temp=heap[i];
while(j<=end){
if(j+1<end&&heap[j]>heap[j+1])
j++;
if(temp>=heap[j]){
heap[i]=heap[j];
}else
break;
i=j;
j=j*2+1;
}
heap[i]=temp; //重要,因為i已經過度到後面的j了,所以i的位置一直是空檔
}
template<class T>
void Heap<T>::shift_up(int cursor) //上濾
{
int i=(cursor-1)/2; //i初始化為上濾下界的一半的位置,確保可以得到父節點
int j=cursor;
T temp=heap[i];
while(i>=0){
if(j+1<_size&&heap[j]>heap[j+1]) //兄弟節點之間比較大小,選擇較為小的那個
j++;
if(heap[i]<heap[j])
break;
else{
heap[j]=heap[i];
}
j=i; //j獲得i的位置
i=(i-1)/2; //i向上迭代
}
heap[j]=temp; //同上面的思路一樣,這次j是一個空檔,只是保留了原i的資料
}
template<class T>
void Heap<T>::show_heap()
{
for(int i=0;i<_size;i++){
cout<<heap[i]<<",";
}
cout<<endl;
}
int main(int *args[])
{
int test[10]={7,5,82,56,66,71,1,6,25,14};
Heap<int> h(test,(int)(sizeof(test)/sizeof(int)));
h.show_heap();
}
由於發的時間有限,註釋做的也不是很詳細,裡面有一些原理我還沒做上解釋,暫且先當上一篇草稿,以免以後忘記。