当前位置: 首页 > news >正文

堆排序(算法实现)

文章目录

  • 堆排序-算法实现
    • 1. 向上调整和向下调整比较
    • 2. 堆排序
      • 1. 升序
      • 2. 降序

堆排序-算法实现

前面介绍了堆的基本功能实现(https://blog.csdn.net/m0_46343224/article/details/127986662),了解了堆,这里用堆实现排序

1. 向上调整和向下调整比较

思考:向上调整和向下调整哪个更优?

此图解析:向上调整的时间复杂度:O(N*log2(N));向下调整的时间复杂度:O(N);则从尾向下调整优于向上调整

2. 堆排序

堆排序思路:

升序:首先建大堆,然后交换首尾数据(也就是把最大的数据放在尾部,再从头向下调整size-1个数据(也就是不对其交换后的最大的数据调整)

降序:首先建小堆,然后交换首尾数据(也就是把最大的数据放在尾部,再从头向下调整size-1个数据(也就是不对其交换后的最大的数据调整)

1. 升序

void SwapData(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

void AdjustDownSortAscending(int* a, int size, int parent)
{
	//假设默认左孩子大
	int lchild = parent * 2 + 1;

	while (lchild < size)
	{
		//确认指向大的孩子
		if (lchild + 1 < size && a[lchild + 1] > a[lchild])
		{
			++lchild;
		}
		//大堆
		//lchild + 1 < size 表示最后的父节点和左孩子对比
		if (a[parent] < a[lchild])
		{
			SwapData(&a[parent], &a[lchild]);
			parent = lchild;
			lchild = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void HeapSortAscending(int* a, int size)
{
	//建大堆(从尾元素父节点开始)
	for (int i = (size - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDownSortAscending(a, size, i);
	}

	int heapend = size - 1;
	while (heapend > 0)
	{
		SwapData(&a[0], &a[heapend]);
        //从首开始向下调整
		AdjustDownSortAscending(a, heapend, 0);
		heapend--;
	}
}

2. 降序

void SwapData(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

void AdjustDownSortDescending(int* a, int size, int parent)
{
	//假设默认左孩子大
	int lchild = parent * 2 + 1;

	while (lchild < size)
	{
		//确认指向大的孩子
		if (lchild + 1 < size && a[lchild + 1] < a[lchild])
		{
			++lchild;
		}
		//大堆
		//lchild + 1 < size 表示最后的父节点和左孩子对比
		if (a[parent] > a[lchild])
		{
			SwapData(&a[parent], &a[lchild]);
			parent = lchild;
			lchild = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void HeapSortDescending(int* a, int size)
{
	//建小堆(从尾元素父节点开始)
	for (int i = (size - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDownSortDescending(a, size,i);
	}

	int heapend = size - 1;
	while (heapend > 0)
	{
		SwapData(&a[0], &a[heapend]);
        //从首开始向下调整
		AdjustDownSortDescending(a, heapend, 0);
		heapend--;
	}
}

为什么升序建立大堆,降序建立小堆?

我们知道大堆小堆都不是连续递减或递增的,拿升序来说:如果建立小堆,那么我们不一定数据连续递增的情况时,这样就增加的时间复杂度,本来可以在O(N*log2(N))时间解决,但是这里不连续递增,就要对没有连续递增的位置上再次调整。降序建立大堆也是一样提高了不必的时间成本

相关文章:

  • antd table 表格滚动高度适配
  • 云原生周刊 | 波音公司允许员工给开源项目做贡献
  • IPv6通信实验
  • 【微信小程序】列表渲染wx:for
  • 链表OJ题+牛客题
  • 使用Cpolar+freekan源码 创建在线视频网站
  • (HAL库)实验1 点亮一个LED
  • 小学生python游戏编程arcade----敌人自动移向角色并开火类的实现
  • java高级篇 Mybatis-Plus
  • 【数据结构】链表
  • 整夜我的背影是一条踏往星空的道路
  • java-net-php-python-jspm小区物业管理系统设计计算机毕业设计程序
  • CentOS 软件包 rpm 管理学习笔记
  • 对比Python,PySpark 大数据处理其实更香
  • 个人开发者轻松接入支付回调
  • vue3的面试题
  • 872. 最大公约数(史上最详细讲解 7种算法,STL+算法标准实现)
  • 计算机基础学习(好文必看)
  • 换工作有感
  • C++ Visual Studio 2022 中的改进、行为更改和错误修复
  • 短剧迷|《权宠》一出,《名不虚传》
  • 西湖大学2025年上海市综合评价招生简章发布
  • 人民日报评论员:焕发风雨无阻、奋勇前行的精气神
  • 中央宣传部、全国总工会联合发布2025年“最美职工”先进事迹
  • 结婚这件事,年轻人到底怎么想的?
  • 金砖国家外长会晤发表主席声明,强调南方国家合作