您的位置:首页 > 其它

排序算法04:堆排序

2012-07-10 14:02 323 查看
最近复习《数据结构与算法分析》,发现其中堆排序算法不完整,因此写来看看。

参考/article/4718950.html

#include <stdio.h>
#define N 10

// 二叉堆中的元素个数为N,那么其中最后一个非叶节点为A[N/2 - 1],调整的时候需要从最后一个非叶节点开始交换
int A
= {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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: