[C/C++]数据结构 堆排序(详细图解)

一:前言

在**C/C++数据结构 堆的详解** 中,介绍了什么是堆,并且完成了堆的实现和一系列接口,包括向上调整法和向下调整法等,接下来小编介绍一个有点量级的排序方法------堆排序,时间复杂度为O(n*lgn)

二:堆排序详解

2.1 方法介绍

1.首先将待排序数组建为大堆,此时堆顶元素就为数组最大值了

2.交换堆顶和堆尾元素,此时最大元素就到了堆尾,目前数组最大元素就排好了,现在就假设堆里没有当前这个最大元素了,堆头下面的左右子树仍然是大堆,只需要再将堆顶元素向下调整到合适位置,剩下的n-1个元素还是大堆

3.堆头堆尾交换,向下调整,如此反复就可排序

ps.排序以升序为例,升序建大堆,降序建小堆


那么怎么将待排序数组建为大堆呢?

假设数组第一个元素是堆,再把第二个元素插入,向上调整为堆,插入第三个元素时,前两个是堆,向上调整,插入第四个元素时,前三个元素是堆,以此反复就可以把所有元素建为堆

复制代码
//建堆
	for (int i = 1; i < size; i++)
	{
		AdjustUp(a, i);
	}

2.2 排序

假设我们的待排序数组为:

建好大堆以后就可以开始排序了

过程如下:

处理最大元素:

先将堆头元素和堆尾元素交换

忽略9,将1向下调整到合适位置

处理次大元素:

再次堆头堆尾交换

忽略8和9,将1向下调整到合适位置

处理第三大元素:

堆头堆尾交换

忽略6和8和9,将2向下调整到合适位置

处理第N大元素:

........................

其实堆排序的实质就是选择排序,每次可以选出一个最大数,放在堆尾,再去处理前n-1个数

代码实现:

复制代码
#include<stdio.h>
typedef int HeapDataType;

void swap(HeapDataType* a, HeapDataType* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
//大堆
void AdjustUp(HeapDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child>0)
	{
		if (a[parent] < a[child])
		{
			swap(&a[parent], &a[child]);
			child = parent;
			parent = (parent - 1) / 2;
		}
		else
		{
			break;
		}
	}
}
//大堆
void AdjustDown(HeapDataType* a, int size, int parent)
{
	int child = parent * 2 + 1;

	while (child<size)
	{
		//找较大的孩子
		if (a[child + 1] > a[child] && child+1<size)
		{
			child = child + 1;
		}

		if (a[parent] < a[child])
		{
			swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void HeapSort(HeapDataType* a, int size)
{
	//建堆
	for (int i = 1; i < size; i++)
	{
		AdjustUp(a, i);
	}
	//排序:升序
	int end = size - 1;
	while (end>0)
	{
		swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);  //end指最后一个元素,同时end的值为前面元素的个数
		end--;
	}
}
测试:
复制代码
int main()
{
	int a[] = { 9,8,6,5,4,2,2,1 };
	HeapSort(a, sizeof(a) / sizeof(a[0]));
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}
相关推荐
码客-ygluu4 分钟前
X3 LUA 异步分布式微服务集群框架
c++·架构·lua
九英里路3 小时前
protobuf快速上手
网络·c++·中间件·json·谷歌·序列化·protobuf
纪念 2293 小时前
C++ 算法基础 (差分)
开发语言·c++·算法
ShineWinsu8 小时前
对于Qt:QTreeWidget常见属性以及QTreeWidgetItem类的解析
开发语言·c++·qt·gui·客户端·多叉树·qtreewidget
落羽的落羽9 小时前
【C++】C++17的主要特性
linux·服务器·开发语言·c++·算法·机器学习
【心态好不摆烂】9 小时前
数据结构基础精讲3
数据结构·算法
岑梓铭9 小时前
《考研408数据结构》第七章(B树 和 B+树)复习笔记
数据结构·笔记·b树·考研·408
汉克老师14 小时前
《从C++小白到算法高手:GESP 1—8级成长地图》第一讲:认识GESP——从编程新手到算法探索者
c++·gesp·信息学竞赛·小学生学c++
岑梓铭15 小时前
《考研408数据结构》第八章(排序)复习笔记
数据结构·笔记
晴天的雨.99216 小时前
【C++】继承篇
java·开发语言·c++