堆和哈希表的實現以及應用(一)

       首先我來和大家一起了解一下堆的一些問題。堆是一個非常實用的數據結構,在一些算法的優化和一些高級數據結構上都能用到堆。比如優先隊列、hash_map、迪傑斯特拉算法(最短路的優化)等等,所以我們大家學好堆是有必要的,對我們學習高深的一些算法和數據結構非常的有用。

       我所知道的堆有已下幾種:二叉堆(就是我們平常說的堆)、二項堆、斐波那契堆;其中後者都是前者的優化。今天呢,由於我的水平有限,只能和大家一起探討一下二叉堆了。

二叉堆堆的一些基本知識

       二叉堆是一種特殊的,二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足堆特性:父結點的鍵值總是大於或等於(小於或等於)任何一個子節點的鍵值,且每個結點的左子樹右子樹都是一個二叉堆(都是最大堆最小堆)。當父結點的鍵值總是大於或等於任何一個子節點的鍵值時爲最大堆。 當父結點的鍵值總是小於或等於任何一個子節的鍵值時爲最小堆

二叉堆的存儲方式

       二叉堆一般用數組來表示。例如,根結點在數組中的位置是1,第n個位置的子節點分別在2n和2n+1。因此,第1個位置的子節點在2和3,第2個位置的子節點在4和5。以此類推,這種存儲方式便於尋找父節點和子節點。如下圖兩個堆:

左圖是小根堆;右圖是大根堆

   	1               11
      /   \           /   \
     2     3         9     10
    / \   / \       / \    / \
   4   5  6  7     5   6  7   8
  / \ / \         / \ / \
 8  9 10 11      1  2 3  4

如下是小根堆的實現過程:

#define MAXN 10000

template<typename Type>
class Heap{
    private:
        int  size;
        Type data[MAXN+1];
        void siftdown( int pos );
        
    public:
        Heap();
        void push( Type key );
        Type pop();
        void make_heap();
        bool empty();
        void clear();
        int  get_size();
};

template<typename Type>
Heap<Type>::Heap(){
    size= 0; }
    
template<typename Type>
int Heap<Type>::get_size(){
    return size; }

template<typename Type>
bool Heap<Type>::empty(){
    return size== 0;}
    
template<typename Type>
void Heap<Type>::clear(){
    size= 0; }

template<typename Type>
void Heap<Type>::siftdown( int pos ){
    while( pos<<1<= size ){
        int t= pos<<1; 
        if( (pos<<1)+ 1<= size && data[(pos<<1)+1]<data[t] ) t= (pos<<1)+ 1;
        if( data[t]< data[pos] ){
            Type tmp= data[t]; data[t]= data[pos]; data[pos]= tmp;
            pos= t; }
        else break;
    }
}

template<typename Type>
void Heap<Type>::push( Type key ){
    data[++size]= key;
    int pos= size;
    while( pos> 1 ){
        if( data[pos>>1]> data[pos] ){
            Type tmp= data[pos]; 
            data[pos]= data[pos>>1]; data[pos>>1]= tmp;
            pos>>= 1; }
        else break;
    }
}

template<typename Type>
Type Heap<Type>::pop(){
    Type tmp= data[1]; data[1]= data[size];
    data[size]= tmp; size--;
    siftdown(1); return data[size+1];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章