/*
堆排序
利用完全二叉樹的性質,將數組看成是一棵完全二叉樹的順序存儲結構,
一個完全二叉樹,必有非葉結點 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;
}
堆排序 小結
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.