Heap Sorting 總結 (C++)


各位讀者,大家好。 因為算法和數據結構相關的知識都是在國外學的,所以有些詞匯翻譯的可能不准確,然后一些源代碼的注釋可能是英文的,如有給大家帶來什么不方便,請見諒。今天我想寫一下Heap相關的知識,從基本的結構到最后的一些常用functions. Heap 的數據結構其實可以看成Array, 例如a[] = {5,3,6,8,2,1,0}這個數組, 我們可以將其看作如下的結構:

Heap又可以分成2種類型:Max-Heap 和 Min-Heap。 Max-Heap的意思是每一個node的key值都要大於它的children的key值;反之Min-Heap的的結構是每個node的key值都小於它的children的key值。 例如一個Max-Heap的結構如下:

對於以上的Heap 數據結構的分析,可以分析出對於一個含有N個元素的heap或者稱之為array,其heap的結構的的高度(level)是1+logN. 例如上面的結構就是1+log7 = 3 層。

如果一個heap當中只有一個element破壞了Max-heap/Min-Heap structure的結構,那么如果希望重構這個heap讓其重新維持Max/Min的話,這個element需要跟它的children中的較大的值交換,一直交換到它的children都小於它的key值為止,這個過程最多進行這個tree的高度次(即:the height of tree), 而這個height就是O(logN)。我們稱這個過程為Max-Heapify或者Min-Heapify。以下展示的是C++的代碼來實現Max-heapify的過程, 如下:

/*
 heapify() function is used to keep the heap structure as max/min heap. If there is a node voilate the max/min heap, this function will try to correct it and restructure it still keep the max/min heap property.
 
 parameter: 1. a[], the array
            2. i; where the node violate the max/min heap
            3. n; the numbers of the a[];
 
 return: void
 
 */
void heapify(int a[], int i, int n){
    
    int j, temp;
    j = 2*i;//the node i's left node
    
    if (j >= n){//i is the leaf of the tree
        
        return;
    }
    
    temp = a[i];
    
    while (j < n) {//i is not the leaf
        
        
        if (a[j]<a[j+1]) {//left child is less than right child
            
            j = j + 1;
        }
        
        if (temp>a[j]) {
            
            break;
        }
        
        if (temp <= a[j]) {// if node i violate the structure, exchange the values.
            
            a[j/2] = a[j];
            a[j] = temp;
            j = j * 2;
        }
        
    }
}

以上的代碼展示的是max-heapify 的過程, 那么如何將一個亂續的heap或者array重構成一個max-heap或者min-heap呢?其實有了以上的功能,將一個完全雜亂的heap裝換成max-heap就很簡單了。我們只需要從倒數第二層的最左邊的一個element開始一直向上面的level的nodes做Max-heapify的過程utill to the root of the tree, 最后就一定能將整個heap轉化成Max-Heap. 倒數第二層的最左邊的一個element的index是N/2 - 1; 這中間的整個過程如下所示:

 

將整個unsorted heap轉化成Max-Heap的過程的時間復雜度Efficiency = O(N), 而不是O(LogN); 這個復雜度的推導過程下次再跟大家解釋,是通過數學運算推導出來的,這里就不詳細解釋了。其實這個代碼很簡單,他的C++的實現代碼如下:

/*
 
 buildMaxHeap functions is used to force and restructure the heap to an maximum heap structure
 parameters: 1: a[];
             2: n;// the number of the arrary
 
 return void
 */

void buildMaxHeap(int a[], int n){
    
    for (int i = n/2-1; i >= 1; i --) {
        
        heapify(a, i, n);
    }
    
}

進過以上的過程,我們知道了如何將一個無序的heap或者array轉換成Max-Heap, 那么接下來我們就解釋一下如何將獲得的Max-heap進行排序,它主要經過一下幾個過程:

1. 交換heap的最后一個key a[N]和heap的root的key a[1]; 此時a[1]破壞了Max-heap的structure,a[N]是最大值。

2. 我們對除了最后幾個已經交換過值的elements剩下的tree進行heapfy的過程;//假如從[j.....N]的elements是之前比較過的,那么就只對[1......j-1]進行heapify的過程。

其具體的c++代碼的實現過程如下所示:

/*
 heapSort function is to sort the heap in an descending or ascending order
 
 parameter:
 1, a[], //the array
 2, n,// how many nodes should be checked in the heapify function, actuall here is not all the node should be checked
 
 return void
 
 */

void heapSort(int a[], int n){
    
    int temp;
    
    for (int i = n-1; i >= 2; i --) {//the last indices of array is n-1, loop until to the root
        
        temp = a[1];
        a[1] = a[i];
        a[i] = temp;
        
        heapify(a, 1, i-1);
    }
}

綜合以上的不做,我們已經可以完成對一個完全無序的array或者heap進行heap-sort的過程,它的時間復雜度如下:

Efficiency = O(N)+O(1)+O(N*logN) = O(N*logN);

那么heap的總結就結束了,下周准備寫一些Binary Search Tree (BST)的知識。

如果有什么錯誤的地方,歡迎大家留言指正,謝謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM