[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;
}
相关推荐
Y.O.U..7 分钟前
今日八股——C++
开发语言·c++·面试
SweetCode13 分钟前
裴蜀定理:整数解的奥秘
数据结构·python·线性代数·算法·机器学习
Zhichao_9744 分钟前
【UE5 C++课程系列笔记】33——商业化Json读写
c++·ue5
惊鸿.Jh1 小时前
【滑动窗口】3254. 长度为 K 的子数组的能量值 I
数据结构·算法·leetcode
云边有个稻草人1 小时前
【C++】第八节—string类(上)——详解+代码示例
开发语言·c++·迭代器·string类·语法糖auto和范围for·string类的常用接口·operator[]
惊鸿一博2 小时前
c++ &&(通用引用)和&(左值引用)区别
开发语言·c++
爱喝热水的呀哈喽2 小时前
Java 集合 Map Stream流
数据结构
Dovis(誓平步青云)2 小时前
【数据结构】排序算法(中篇)·处理大数据的精妙
c语言·数据结构·算法·排序算法·学习方法
nuo5342022 小时前
黑马 C++ 学习笔记
c语言·c++·笔记·学习
Touper.2 小时前
L2-003 月饼
数据结构·算法·排序算法