2016-10-24 4 views
1

私は最大ヒープを構築することを理解し、私はヒープソートaccrossに来ている、と私は、このソースコード反復ソート

/ 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); 
} 

に来て、我々は0にN/2から反復処理する必要があります配列内のすべての要素を取得するためのインデックス。しかし、なぜヒープソートで、最初にルートを置き、最初に最後の要素をとり、ヒープのサイズを小さくすると、1つのインデックスからのみiteratreするのですか?我々は、n/2の要素を反復処理していたオリジナルの最大ヒープを作成するときに

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); 
    } 

は、なぜこれが最大ヒープを作成します使用して

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

として宣言。

例を見れば分かりやすいでしょう。今からヒープを再調整する時間です

 5 
    1  3 
    2 4 6 0 

そして、あなたは1ずつ数を減らす:あなたは、ヒープ内の最後の項目でルートを交換する場合は、あなたが得る

 0 
    1  3 
    2 4 6 5 

:このヒープを考えてみましょうトップダウン。あなたが見ているアイテムがいずれの子供よりも大きい場合は、それを小さな子供と交換するという規則があります。従って:

 1 
    5  3 
    2 4 6 0 

そしてもう一度。 。 。

 1 
    2  3 
    5 4 6 0 

ヒープは再び有効です。

ここで重要な点は、ルートノードを置き換えるときに、いくつかのノードを調整するだけでよいことです。このは常にです。調整は最大でlog(n)個のノード(基本的にツリーの高さ)に影響します。大部分が影響を受けていないときにヒープ全体を再構築する必要はありません。