最近複習《數據結構與算法分析》,發現其中堆排序算法不完整,因此寫來看看。
參考http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html
#include <stdio.h>
#define N 10
// 二叉堆中的元素個數爲N,那麼其中最後一個非葉節點爲A[N/2 - 1],調整的時候需要從最後一個非葉節點開始交換
int A[N] = {9,8,7,6,5,4,3,2,1,0};
void Swap(int *X, int *Y)
{
int Tmp;
Tmp = *X;
*X = *Y;
*Y = Tmp;
}
void Print()
{
printf("Swap: ");
for(int i = 0; i < N; i++)
{
printf("%d ", A[i]);
}
printf("\n");
}
// 遞歸調整順序
void HeapAdjust(int M, int T)
{
int LeftChild = 2 * M + 1;
int RightChild = 2 * M + 2;
if(LeftChild < T && A[M] < A[LeftChild])
{
Swap(&A[M], &A[LeftChild]);
Print();
}
if(RightChild < T && A[M] < A[RightChild])
{
Swap(&A[M], &A[RightChild]);
Print();
}
if(LeftChild < T)
HeapAdjust(LeftChild, T);
if(RightChild < T)
HeapAdjust(RightChild, T);
//Print();
}
void BuildHeap()
{
for(int Mid = N / 2 - 1; Mid >= 0; Mid--)
{
HeapAdjust(Mid, N);
}
printf("BuildHeapFinished\n");
}
void HeapSort()
{
// 首先對初始堆排好序
BuildHeap();
// 然後根據剩餘元素個數來循環,每次循環會刪掉一個最大值,這個最大值通過與堆頂元素交換而來。
// 當只剩餘一個元素循環停止,該元素就是最小的值
for(int i = N - 1; i >= 1; i--)
{
printf("---------------------\n"); // 交換第一個和最後一個
Swap(&A[0], &A[i]);
Print();
HeapAdjust(0, i);
}
}
int main()
{
Print();
HeapSort();
Print();
return 0;
}
實際上只要理清了思路,寫起來也容易,我上面的代碼不是太簡潔,不錯測試沒有發現問題,每次交換的結果也都列出來了,如下圖所示:
爲了適應輸入文件的需求,更改上面代碼,將數組A[]和N作爲參數傳入到函數中。
#include "HeapSort.h"
#include "Print.h"
void Swap(int *X, int *Y)
{
int Tmp;
Tmp = *X;
*X = *Y;
*Y = Tmp;
}
// 遞歸調整順序
void HeapAdjust(int A[], int N, int M, int T)
{
int LeftChild = 2 * M + 1;
int RightChild = 2 * M + 2;
if(LeftChild < T && A[M] < A[LeftChild])
{
Swap(&A[M], &A[LeftChild]);
//Print(A, N);
}
if(RightChild < T && A[M] < A[RightChild])
{
Swap(&A[M], &A[RightChild]);
//Print(A, N);
}
if(LeftChild < T)
HeapAdjust(A, N, LeftChild, T);
if(RightChild < T)
HeapAdjust(A, N, RightChild, T);
//Print();
}
void BuildHeap(int A[], int N)
{
for(int Mid = N / 2 - 1; Mid >= 0; Mid--)
{
HeapAdjust(A, N, Mid, N);
}
//printf("BuildHeapFinished\n");
}
void HeapSort(int A[], int N)
{
// 首先對初始堆排好序
BuildHeap(A, N);
// 然後根據剩餘元素個數來循環,每次循環會刪掉一個最大值,這個最大值通過與堆頂元素交換而來。
// 當只剩餘一個元素循環停止,該元素就是最小的值
for(int i = N - 1; i >= 1; i--)
{
//printf("---------------------\n"); // 交換第一個和最後一個
Swap(&A[0], &A[i]);
//Print(A, N);
HeapAdjust(A, N, 0, i);
}
}
耗時 Time = 4694ms。