1. 程式人生 > >經典堆排序,友情附贈註釋c++

經典堆排序,友情附贈註釋c++

堆排序可直接用於陣列排序,因為a[k]的孩子節點為a[2*k]和a[2*k+1]

本例程式碼來自演算法C語言實現一書,這麼多年看AInC,放心!

#include<iostream>
using namespace std;

void exch(int& a, int& b)
{
    int temp = a;
    a = b;
    b = temp;
}

void fixdown(int* a, int k, int N)//將節點K調整到他該在的位置,此處為大根堆,因此a[k]如果小,則向下移動
{
    int j;
    while(2*k <= N)
    {   
        j = 2*k;
        if(j < N && a[j]<a[j+1])//與子節點中較大的交換
        {   
            j++;
        }   
        if(a[k] > a[j]) break;//如果a[k]比子節點都大,那麼就不必移動了
        exch(a[k],a[j]);
        k = j;
    }   
}

void heapsort(int* a, int l , int r)
{
    int k;
    int N = r-l+1;
    int* pq = a+l-1;
    for(k = N/2; k >= 1; k--)//調整有孩子節點的節點位置,由下至上構造大根堆
    {   
        fixdown(pq,k,N);
    }   

    while(N > 1)//將最大的節點交換移動至陣列尾部,然後將交換上來的小值節點重新向下移動調整,構造大根堆
    {   
        exch(pq[1],pq[N]);
        fixdown(pq,1,--N);
    }   
}

int main(){
    int a[11] = {6,4,9,3,8,4,5,1,2,4,8};
    heapsort(a,0,10);
    for(int i = 0 ; i < 11; i++)
        cout<<a[i]<<" ";
    cout<<endl;
    return 0;
}