[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;
}
相关推荐
zh_xuan2 小时前
c++ 单例模式
开发语言·c++·单例模式
int型码农4 小时前
数据结构第八章(一) 插入排序
c语言·数据结构·算法·排序算法·希尔排序
利刃大大4 小时前
【在线五子棋对战】二、websocket && 服务器搭建
服务器·c++·websocket·网络协议·项目
喜欢吃燃面4 小时前
C++刷题:日期模拟(1)
c++·学习·算法
SHERlocked935 小时前
CPP 从 0 到 1 完成一个支持 future/promise 的 Windows 异步串口通信库
c++·算法·promise
怀旧,5 小时前
【数据结构】6. 时间与空间复杂度
java·数据结构·算法
积极向上的向日葵5 小时前
有效的括号题解
数据结构·算法·
Java 技术轻分享5 小时前
《树数据结构解析:核心概念、类型特性、应用场景及选择策略》
数据结构·算法·二叉树··都差速
虚拟之6 小时前
36、stringstream
c++
我很好我还能学6 小时前
【面试篇 9】c++生成可执行文件的四个步骤、悬挂指针、define和const区别、c++定义和声明、将引用作为返回值的好处、类的四个缺省函数
开发语言·c++