排序算法04:堆排序

最近複習《數據結構與算法分析》,發現其中堆排序算法不完整,因此寫來看看。

參考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。

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