堆排序

百度面試二輪遊,就像CP3摸不到西決地板一樣,兩輪面試都問到堆排序,感覺這個排序既考查數據結構,又考察排序算法, 可是反應一個人的基礎。第一面的時候還不會,用快速排序代替了,寫的還可以;第二面又問到,但是之前我有看過了,可是寫代碼還是很費勁,最後的最後,終究被pass掉了。
回來怒寫了一遍堆排序:

#include<stdio.h>
int h[101];//全局變量,用數組來存儲堆,從h[1]開始
int n;     //有n個元素    
void swap(int x,int y)//交換兩個索引的值
{
    int t;
    t = h[x];
    h[x] = h[y];
    h[y] = t;
    return;
}

void siftdown(int i)//調整堆,建立最大根堆
{
    int t;//臨時變量,用於標記父節點,左節點,右節點中值最大的節點
    int flag = 0;//臨時變量用作標誌,判斷是否還需要繼續向下比較
    while(i*2 <= n && flag == 0) //有左節點且需要繼續比較
    {
        if(h[i*2] > h[i])//左節點的值大於父節點
            t = i * 2;
        else
            t = i;

        if(2*i+1 <= n) //如果有右節點
            if(h[i*2+1] > h[t])
                t = i*2+1;
            else
                t = t;

        if(i != t)//如果父節點的值不是最大的值,需要和子節點交換
        {
            swap(i,t);//交換兩個索引的值
            i = t; //在與父節點交換後的子節點位置上,繼續往下比較,看是否他的子節點還有大於他的值的。
        }
        else
            flag = 1;//不需要比較了,因爲下邊都是最大堆的順序
    }
    return;
}

void create()//建立一個最大根堆
{
    int i;
    for(i=n/2;i>=1;i--)//從最後一個非葉子節點開始向上調整
    {
        siftdown(i);
    }
    return;
}

void heapsort()
{
    while(n>1)   //最後調整到n爲2 就可以了,就是2索引和1索引交換
    {
        swap(1,n);//開始1索引處爲最大值,交換到n索引處即數組末尾
        n--;
        siftdown(1);//調整從末尾交換過來的值,再次恢復最大根堆
    }
    return;
}

int main()
{
    int i,num;
    printf("Please input the number of elements:\n");
    scanf("%d",&num);
    n = num;
    for(i=1;i<=n;i++)
    {
        printf("Please input %d elements:\n",i);
        scanf("%d",&h[i]);
    }

    create();

    heapsort();

    for(i=1;i<=num;i++)
    {
        printf("%d ",h[i]);
    }
    return 0;
}

程序輸入測試和運行結果:

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章