当前位置: 代码网 > it编程>编程语言>C/C++ > 【数据结构与算法】堆排序算法原理与实现:基于堆实现的高效排序算法

【数据结构与算法】堆排序算法原理与实现:基于堆实现的高效排序算法

2024年07月31日 C/C++ 我要评论
堆排序算法是一种高效且实用的排序算法,它通过利用堆数据结构的特点和性质,实现了对数据的高效排序。在实际应用中,我们可以根据问题的特点选择使用堆排序算法,以提高程序的性能和效率。

目录

一、引言

堆排序的简介

堆排序的特点

二、堆的概念

三、堆排序算法的原理

四、堆排序的步骤

🍃构建堆 

🍃交换与调整

🍃重复过程

五、堆排序的性能分析

🍃时间复杂度:

🍃空间复杂度:

六、示例代码

七、总结


 

一、引言

堆排序的简介

堆排序的特点

 

二、堆的概念

 

三、堆排序算法的原理

四、堆排序的步骤

🍃构建堆 

 这里分别给出向下调整建小堆和向下调整建大堆的算法

(如果关于向上调整算法和向下调整算法有疑惑,建议了解完堆的这篇文章之后再来看

【数据结构与算法】探索数组在堆数据结构中的妙用:从原理到实现-csdn博客

void adjustdownsmall(datatype* a, int parent, int size)//向下调整建小堆算法
{
	
	int child = parent * 2 + 1;//先假定左孩子小
	while (child < size)//循环条件是未调整至叶子节点
	{
		if (child + 1 < size && a[child + 1] < a[child])//如果右孩子存在且更小,改变为右孩子
			child++;
		if (a[child] < a[parent])//如果子节点小于父节点,交换位置
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}
void adjustdownbig(datatype* a, int parent, int size)//向下调整建大堆算法
{
	
	int child = parent * 2 + 1;//先假定左孩子大
	while (child < size)//循环条件是未调整至叶子节点
	{
		if (child + 1 < size && a[child + 1] > a[child])//如果右孩子存在且更大,改变为右孩子
			child++;
		if (a[child] > a[parent])//如果子节点大于父节点,交换位置
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}


 

🍃交换与调整

swap(&a[0], &a[end]);//交换堆顶和堆尾数据
end--;
adjustdownsmall(a, 0, end);//向下调整恢复堆的结构

 9b7e5cb844404312a312e019bae3b8bd.png

 

🍃重复过程

 

五、堆排序的性能分析

🍃时间复杂度:

 

🍃空间复杂度:

六、示例代码

(分别给出了完整的降序排序算法和升序排序算法)

#include<stdio.h>
#include<stdlib.h>

#if 1
//堆排序
typedef int datatype;
void swap(datatype* a, datatype* b)
{
	datatype tmp = *a;
	*a = *b;
	*b = tmp;
}
void adjustdownsmall(datatype* a, int parent, int size)//向下调整建小堆算法
{
	
	int child = parent * 2 + 1;//先假定左孩子小
	while (child < size)//循环条件是未调整至叶子节点
	{
		if (child + 1 < size && a[child + 1] < a[child])//如果右孩子存在且更小,改变为右孩子
			child++;
		if (a[child] < a[parent])//如果子节点小于父节点,交换位置
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}
void adjustdownbig(datatype* a, int parent, int size)//向下调整建大堆算法
{
	
	int child = parent * 2 + 1;//先假定左孩子大
	while (child < size)//循环条件是未调整至叶子节点
	{
		if (child + 1 < size && a[child + 1] > a[child])//如果右孩子存在且更大,改变为右孩子
			child++;
		if (a[child] > a[parent])//如果子节点大于父节点,交换位置
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}

void heapsortdorder(datatype* a,int size)//降序排序
{
	
	//向下调整建小堆
	for (int i = (size - 2) / 2; i >= 0; i--)//从最后一个父节点调整
	{
		adjustdownsmall(a, i, size);
	}
	int end = size - 1;
	while (end>0)
	{
		swap(&a[0], &a[end]);//交换堆顶和堆尾数据
		end--;
		adjustdownsmall(a, 0, end);//向下调整恢复堆的结构
	}
}
void heapsortaorder(datatype* a, int size)//升序排序
{

	//向下调整建大堆
	for (int i = (size - 2) / 2; i >= 0; i--)//从最后一个父节点调整
	{
		adjustdownbig(a, i, size);
	}
	int end = size - 1;
	while (end > 0)
	{
		swap(&a[0], &a[end]);//交换堆顶和堆尾数据
		end--;
		adjustdownbig(a, 0, end);//向下调整恢复堆的结构
	}
}
#endif

void print(datatype* a, int size)
{
	for (int i = 0; i < size; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}
int main()
{
	int arr[] = { 12,3,5,78,46,15,23,19,20,36,52 };
	int size = sizeof(arr) / sizeof(arr[0]);
	heapsortdorder(arr, size);//降序
	print(arr, size);
	heapsortaorder(arr, size);//升序
	print(arr, size);

}

 27c88bb4be3d4b43beb24363a0fd02ae.png

七、总结

 

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com