栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C语言数据结构】堆排序

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C语言数据结构】堆排序

给定一个有n个数据的数组,将其排列为升序或者降序。

//这里是下面用的到的升降序排序函数代码
//向下排序
void AdjustDown(int* a, int n, int parent)
{
	assert(a);
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n && a[child] < a[child + 1])
		//                    如果建立小堆这里应变为>
			child++;
		if (a[child] > a[parent])
		//     如果建立小堆这里应变为<
		{
			int tmp = a[parent];
			a[parent] = a[child];
			a[child] = tmp;

			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}
//向上排序
void Adjustup(int* hp, HeapDataType child)
{
	assert(hp);
	int parents = (child - 1) / 2;
	while (child)
	{
		if (hp[child] > hp[parents])
		//  如果建立小堆这里应变为<
		{
			HeapDataType tmp = hp[parents];
			hp[parents] = hp[child];
			hp[child] = tmp;

			child = parents;
			parents = (child - 1) / 2;
		}
		else
			break;
	}
}

这里以升序为例
1.建小堆,排升序。

①将数组的第一个元素看做堆,后面的数据依次加上堆,然后用向上调整构造小堆。

void AdjustUp(int* a, int n)
{
	assert(a);
	int i = 0;
	for (i = 1; i < n; i++)
	{
		AdjustUp(a, i);
	}
}

②倒着走找第一个父节点,然后对这个父节点向下调整,保证它下面的子树都是小堆。
叶节点的子树不需要调整,因为他本身就是小堆;所以从倒着走的第一个非叶节点的子树开始调整。

void AdjustUp(int* a, int n)
{
	assert(a);
	//找出第一个父节点
	int i = (n - 1 - 1) / 2;
	for (int k = i; k >= 0; k--)
	{
		AdjustDown(a, n, k);
	}
}

但是这两种方法只可以将当前的数组列为小堆,只能选出最小的数,而次小的数则找不出来。从第二个位置开始看做堆,但这之前建立的关系全都乱了,只能重新建堆,才能找出次小的数,这样一来很麻烦。所以我们可以换一种思路。

2.排升序,建大堆
①利用上两个方法将当前的数组建成大堆,选出最大的数
②最大的数跟最后一个数交换
③最后一个数不看做堆内元素进行向下调整,即可选出次大的数
以此类推重复,时间复杂度为NlogN

注意:这里的Adjustup和AdjustDown已经和上面的不同,父子节点关系已经改变

void AdjustUp(int* a, int n)
{
	assert(a);
	//建立大堆
	int i = (n - 1 - 1) / 2;
	for (int k = i; k >= 0; k--)
	{
		AdjustDown(a, n, k);
	}
	for (int i = n - 1; i > 0; i--)
	{
	    //将第一个元素和最后一个互换
		int tmp = a[0];
		a[0] = a[i];
		a[i] = tmp;
		//不看最后一个元素向下调整
		AdjustDown(a, i, 0);
		//注意此处i既是最后一个元素的下标,又是删除最后一个元素后前面元
		//素的个数,所以传i就代表了不看最后一个元素
	}
}

如果要排成降序,那么只需要改变AdjustDown和Adjustup内父子元素的关系即可。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/443885.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号