2016-10-24 30 views
1

我來翻過堆排序,我來到這個源代碼迭代最大heapify在堆排序

/ C++ program for implementation of Heap Sort 
#include <iostream> 
using namespace std; 

// To heapify a subtree rooted with node i which is 
// an index in arr[]. n is size of heap 
void heapify(int arr[], int n, int i) 
{ 
    int largest = i; // Initialize largest as root 
    int l = 2*i + 1; // left = 2*i + 1 
    int r = 2*i + 2; // right = 2*i + 2 

    // If left child is larger than root 
    if (l < n && arr[l] > arr[largest]) 
     largest = l; 

    // If right child is larger than largest so far 
    if (r < n && arr[r] > arr[largest]) 
     largest = r; 

    // If largest is not root 
    if (largest != i) 
    { 
     swap(arr[i], arr[largest]); 

     // Recursively heapify the affected sub-tree 
     heapify(arr, n, largest); 
    } 
} 

// main function to do heap sort 
void heapSort(int arr[], int n) 
{ 
    // Build heap (rearrange array) 
    for (int i = n/2 - 1; i >= 0; i--) 
     heapify(arr, n, i); 

    // One by one extract an element from heap 
    for (int i=n-1; i>=0; i--) 
    { 
     // Move current root to end 
     swap(arr[0], arr[i]); 

     // call max heapify on the reduced heap 
     heapify(arr, i, 0); 
    } 
} 

/* A utility function to print array of size n */ 
void printArray(int arr[], int n) 
{ 
    for (int i=0; i<n; ++i) 
     cout << arr[i] << " "; 
    cout << "\n"; 
} 

// Driver program 
int main() 
{ 
    int arr[] = {12, 11, 13, 5, 6, 7}; 
    int n = sizeof(arr)/sizeof(arr[0]); 

    heapSort(arr, n); 

    cout << "Sorted array is \n"; 
    printArray(arr, n); 
} 

我明白,要建立一個最大堆,我們需要從N/2到0迭代索引以便通過數組中的所有元素。但是爲什麼在堆棧中,當我們在最後加上根,最後一個元素在開始,並減少堆的大小時,我們只能從一個索引迭代?

使用

for (int i=n-1; i>=0; i--) 
    { 
     // Move current root to end 
     swap(arr[0], arr[i]); 

     // call max heapify on the reduced heap 
     heapify(arr, i, 0); 
    } 

創建原來最大的堆,我們不得不遍歷N/2的元素時,爲什麼會這樣創造最大堆?

for (int i = n/2 - 1; i >= 0; i--) 
    heapify(arr, n, i); 

爲什麼心不是堆排序聲明

for (int i=n-1; i>=0; i--) 
    { 
     // Move current root to end 
     swap(arr[0], arr[i]); 

     // call max heapify on the reduced heap 
     for(int j = n/2 ,; j >= 0 ; j--) 
      heapify(arr, i, j); 
    } 

回答

2

因爲一旦堆構造,可以去掉根和快速調整堆,通過採取結構的優勢。

通過查看示例可以很容易地看到。考慮這個堆:如果你換根在堆的最後一個項目

 0 
    1  3 
    2 4 6 5 

,您可以:

 5 
    1  3 
    2 4 6 0 

你1。減少計數現在是時候從調整堆自上而下。規則是,如果你看的物品比任何一個都大,那麼將它與最小的孩子交換。所以:

 1 
    5  3 
    2 4 6 0 

再次。 。 。

 1 
    2  3 
    5 4 6 0 

該堆再次有效。

這裏的關鍵是,當你替換根節點時,你只需要調整幾個節點。這個總是的作品。調整最多會影響log(n)節點(基本上,樹的高度)。當大部分堆沒有受到影響時,不需要重新構建整個堆。