1、算法基本思想
从小到大排序构造大堆,然后两两交换(ps:交换首元素与最后一个元素),每一次交换后向下调整,保持大堆的状态,这样就可以依次得到最大的元素、次大的元素...
2、源代码
交换数据
/*
* 函数名称:Swap
*
* 函数功能:交换数据
*
* 入口参数:a, b
*
* 出口参数:void
*
* 返回类型:void
*/
void Swap(int * a, int * b)
{
int tmp = 0;
assert(NULL != a);
assert(NULL != b);
tmp = *a;
*a = *b;
*b = tmp;
return;
}
向下调整递归
/*
* 函数名称:AdjustDownRecursion
*
* 函数功能:向下调整(递归)
*
* 入口参数:array, parent, size
*
* 出口参数:void
*
* 返回类型:void
*/
void AdjustDownRecursion(int array[], int parent, int size)
{
int maxChild = 0;
int left = parent * 2 + 1;
int right = parent * 2 + 2;
//叶子结点
if (left >= size)
{
return;
}
else if (parent >= size)
{
return;
}
else
{
;
}
//保证右孩子存在
if (right < size)
{
if (array[left] < array[right])
{
maxChild = right;
}
else
{
maxChild = left;
}
}
//右孩子不存在,自然maxChild就是left
else
{
maxChild = left;
}
if (array[parent] >= array[maxChild])
{
return;
}
else
{
Swap(array + parent, array + maxChild);
AdjustDownRecursion(array, maxChild, size);
}
return;
}
/*
* 函数名称:HeapSort
*
* 函数功能:堆排序(向下调整递归)
*
* 入口参数:array, size
*
* 出口参数:void
*
* 返回类型:void
*/
void HeapSort(int array[], int size)
{
int i = 0;
// 从后往前建堆
for (i = (size - 2) / 2; i >= 0; i--)
{
AdjustDownRecursion(array, i, size);
}
// 建好堆后
for (i = 0; i < size; i++)
{
Swap(array, array + size - 1 - i);
// 从根结点开始向下调整保持堆的性质不变
AdjustDownRecursion(array, 0, size - 1 - i);
}
return;
}
向下调整迭代
/*
* 函数名称:AdjustDownLoop
*
* 函数功能:向下调整(迭代)
*
* 入口参数:array, parent, size
*
* 出口参数:void
*
* 返回类型:void
*/
void AdjustDownLoop(int array[], int parent, int size)
{
int maxChild = 0;
int left = parent * 2 + 1;
int right = parent * 2 + 2;
while (1)
{
//叶子结点
if (left >= size)
{
break;
}
else if (parent >= size)
{
break;
}
else
{
;
}
//保证右孩子存在
if (right < size)
{
if (array[left] < array[right])
{
maxChild = right;
}
else
{
maxChild = left;
}
}
//右孩子不存在,自然maxChild就是left
else
{
maxChild = left;
}
if (array[parent] >= array[maxChild])
{
break;
}
else
{
Swap(array + parent, array + maxChild);
parent = maxChild;
left = parent * 2 + 1;
right = parent * 2 + 2;
}
}
return;
}
/*
* 函数名称:HeapSort
*
* 函数功能:堆排序(向下调整迭代)
*
* 入口参数:array, size
*
* 出口参数:void
*
* 返回类型:void
*/
void HeapSort(int array[], int size)
{
int i = 0;
// 从后往前建堆
for (i = (size - 2) / 2; i >= 0; i--)
{
AdjustDownLoop(array, i, size);
}
// 实际上只需要比较size-1次,因为最后会剩下一个元素
for (i = 1; i < size; i++)
{
Swap(array, array + size - i);
// 从根结点开始向下调整保持堆的性质不变
AdjustDownLoop(array, 0, size - i);
}
return;
}
main
#define _CRT_SECURE_NO_WARNINGS 1
/*
* Copyright (c) 2018, code farmer from sust
* All rights reserved.
*
* 文件名称:HeapSort.c
* 功能:堆排序
*
* 当前版本:V1.0
* 作者:sustzc
* 完成日期:2018年7月9日13:46:43
*/
# include <stdio.h>
# include <assert.h>
/*
* 函数名称:main
*
* 函数功能:测试主程序
*
* 入口参数:void
*
* 出口参数:0
*
* 返回类型:int
*/
int main(void)
{
int i = 0;
int numbers[] = {3, 1, 6, 4, 5, 2};
int len = sizeof(numbers) / sizeof(int);
printf("排序之前:\n");
for (i = 0; i < len; i++)
{
printf("%d ", numbers[i]);
}
HeapSort(numbers, len);
printf("\n排序之后:\n");
for (i = 0; i < len; i++)
{
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
3、输出结果