【C】排序算法之堆排序

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、输出结果


猜你喜欢

转载自blog.csdn.net/sustzc/article/details/81055733