2016-10-24 2 views
1

내가 힙 정렬 건너왔다, 내가반복 정렬

/ 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에서 반복 할 필요가 배열의 모든 요소를 ​​처리하기위한 인덱스. 하지만 힙이 왜 우리가 마지막에 루트를두고 시작 부분에 마지막 요소를 놓고 힙의 크기를 줄이면 하나의 인덱스에서만 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) 개의 노드 (기본적으로 트리의 높이)에 영향을줍니다. 대부분의 경우 영향을받지 않을 때 전체 힙을 다시 작성할 필요가 없습니다.

관련 문제