堆排序 小結

/*
  堆排序
  利用完全二叉樹的性質,將數組看成是一棵完全二叉樹的順序存儲結構,
  一個完全二叉樹,必有非葉結點 LEN / 2個,
  一個葉結點的根結點位置 爲 Root = Child / 2
                            LChild = Root * 2
                            RChild = Root * 2 + 1


  基本排序思想:
  1.將要排序的數組創建爲一個大根堆,堆頂元素爲堆中最大元素。
  2.將堆頂元素,和無序區最後一個元素交換,重新調整大根堆。


  建初始堆所需的比較次數較多,堆排序不適宜於記錄數較少的文件。
*/



#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define  N 11
void Swap(int *fir, int *sec);
void HeapSort(int array[], int length);
void HeapAdjust(int array[], int i, int nLength);
void SmallHeapSort(int array[], int length);
void SmallHeapAdjust(int array[], int i, int nLength);
// 大頂堆 測試
void main()
{
    int array[N + 1];
    int i;

    srand((unsigned int)time(NULL));

    //這裏沒有用第0號數組元素來記錄數組個數,這樣便於計算.
    array[0] = N;
    for (i = 1; i <= N; i++)
    {
        array[i] = rand()%90 + 10;
        printf("%4d", array[i]);
    }
    printf("/n");

    HeapSort(array, N);
//    SmallHeapSort(array, N);

    for (i = 1; i <= N; i++)
    {
        printf("%4d", array[i]);
    }
    printf("/n");
}

void HeapAdjust(int array[], int start, int end)
{

    int tmp = array[start];       //記錄根節點
    int j;

    for (j = 2 * start; j <= end; j = j * 2)   //沿節點值較大的兒子向下篩選
    {
        if (j < end && array[j] < array[j + 1])  //如 RChild > LChild 則指向RChild
            j++;

        if (tmp >= array[j])   //
            break;

        array[start] = array[j];    //較大的兒子向父節點移動,更新父結點位置
        start = j;
    }
    array[start] = tmp;  //將根結點放置到最後空出的合適的位置
}
void HeapSort( int array[], int length )
{
    int i;

    // 建立大頂堆
    for ( i = length / 2 ; i > 0; i-- )
    {
        //層層調整大頂堆
        HeapAdjust( array, i, length ); 
    }
   
//     for (i = 1; i <= N; i++)
//     {
//         printf("%4d", array[i]);
//     }
//     printf("/n");

    //下面執行會很快
    for ( i = length; i > 1; i-- )
    {
        Swap(&array[1], &array[i]);       //交換至有序區
        HeapAdjust(array, 1, i-1);        //重新調整大頂堆
    }

}


//小頂堆就是堆頂放的是最小的數,交換至有序區的時候,就是遞減嘍

void SmallHeapSort(int array[], int length)
{
    int i;

    for (i = length / 2; i > 0; i--)
    {
        SmallHeapAdjust(array, i, length);
    }

    for (i = length; i > 1; i--)
    {
        Swap(&array[i], &array[1]);
        SmallHeapAdjust(array, 1, i - 1);
    }
}
void SmallHeapAdjust(int array[], int start, int end)
{
    int tmp = array[start],
        j;
   
    for (j = start * 2; j <= end; j *= 2)
    {
        if (j < end && array[j] > array[j + 1])
            j++;
           
        if (tmp <= array[j])
            break;
       
        array[start] = array[j];
        start = j;
    }
    array[start] = tmp;
}

void Swap(int *fir, int *sec)
{
    int t;
    t = *fir;
    *fir = *sec;
    *sec = t;
}


發佈了30 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章