iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言数据结构之堆排序的优化算法
  • 334
分享到

C语言数据结构之堆排序的优化算法

2024-04-02 19:04:59 334人浏览 薄情痞子
摘要

目录1.堆排序优化算法1.1建堆的时间复杂度1.1.1 向下调整建堆:O(N)1.1.2 向上调整建堆:O(N*logN)1.2堆排序的复杂度1.2.1原堆排序的时间复杂度

在浏览本篇博文的小伙伴可先浅看一下上篇堆和堆排序的思想:

戳这里可跳转上篇文~~

1.堆排序优化算法

要堆堆排序算法进行优化我们首先要明白之前我们所写的堆排序有什么可以优化的地方或者说哪里写的不够好?

void HeapSort(int* a, int size)
{
	//小堆
	HP hp;
	Heapinit(&hp);
	//O(N*logN)
	for (int i = 0; i < size; ++i)
	{
		HeapPush(&hp, a[i]);
	}
	size_t j = 0;
	//O(N*logN)
	while (!HeapEmpty(&hp))
	{
		a[j] = HeapTop(&hp);
		j++;
		HeapPop(&hp);
	}
	HeapDestory(&hp);
}

这是我们之前写的堆排序,我们能够发现,如果我们要实现堆排序的前提是我们要写一堆。那这想想都很麻烦,我们都知道排序算法那么多,我们何必选择这种算法呢?

其次我们再来分析一下建堆的时间复杂度:

1.1建堆的时间复杂度

因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明 ( 时间复杂度本来看的就是近似值,多几个节点不影响最终结果) :

因为我们要进行优化建堆,在这里分析一下向下调整建堆和向上调整建堆的时间复杂度。

1.1.1 向下调整建堆:O(N)

过程分析如下:

因此向下调整建堆的时间复杂度为O(n)。

1.1.2 向上调整建堆:O(N*logN)

过程分析如下:

 因此向上调整建堆的时间复杂度为O(N*logN)。

1.2堆排序的复杂度

1.2.1原堆排序的时间复杂度

我们来看原堆排序的代码中使用了向上调整建堆,因此原排序的时间复杂度为O(N*logN)

1.2.2原堆排序的空间复杂度

因为我们要建立一个堆,我们实现堆是使用数组实现,因此假设有要排序元素个数为N,空间复杂度为O(N)。

1.3堆排序优化算法的复杂度

堆排序的优化算法主要是对空间复杂度进行优化。由于我们之前建堆都要开辟新的数组,因此我们是否可以在原数组上直接建堆,无需再开辟新的空间建堆呢?答案当然是可以的。以下使用的正是在原数组上直接建堆。

1.3.1 堆排序优化算法的时间复杂度

由于使用堆排序,我们要利用堆的特点,每次取堆顶的元素。因此每次取完数据后都要对堆进行调整。再次我们有向上调整和向下调整两种算法,我们需要对这两种算法分别分析选出一个 更优的调整算法。

1.3.1.1向上调整--建堆 O(N*logN)

由于我们是对原数组之间建堆,因此我们如果要是用向上调整,在刚刚我们所分析的建堆的时间复杂度是O(N*logN)。

实现代码:

	向上调整--建堆  O(N*logN)
	int n = 1;
	while (n<size)
	{
		AdjustUp(a, n++);
	}

1.3.1.2向下调整-建堆 O(N)

由于向下调整的前提条件是左子树和右子树都已经是一个堆,但是一个数组并不能保证是一个堆,那么我们不能直接对数组使用向下调整。因此我们需要将节点的左子树右子树变成堆再进行向下调整。因此我们可以我们可以倒着来。

过程:

1、叶子节点不要调,因为一个节点可以看成堆。因此我们从倒数的第一个非叶子节点开始调整。如果找到倒数第一个非叶子节点。那就是用最后一个节点找他的父节点就是最后一个非叶子节点。

parent = (child-1)/2。我们用size计算:child = size -1。因此parent = (size-1-1)/2。我们一直向上找就可以将数组变成一个堆。因此向下调整建堆的复杂度为O(N)。分析如上:

	//向下调整--建堆  O(N)
	for (int i = (size - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDown(a, size, i);
	}

1.3.2 堆排序优化算法的空间复杂度

由于我们是在原数组上进行遍历因此没有开辟新的空间。因此空间复杂度为O(1)。

1.4堆排序实现逻辑

如果升序建小堆,最小的数已经在堆顶,剩下的数关系打乱,需要重新建堆,建堆最好也要O(N),再选出次小的,不断建堆选数,如果这样,还不如直接遍历选数!!因此升序要建大堆!!利用删除的思想来玩。

过程:

1、把第一个数和最后一个数交换,由于是大堆,堆顶的数据一定是最大的数据。和最后一个数交换后,最大的数据就到了最后一个。

2、再对前N-1个数进行向下调整建立新的大堆,次大的数放在了堆顶,我们再让堆顶的元素和最后一个元素交换(这个最后一个不是数组的最后一个,是堆中的最后一个,使用end进行控制)。

3、当end到0的时候,说明已经排完了。

	//升序要建大堆,
	size_t end = size - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		end--;
	}

1.5堆排序实现代码

void HeapSort(int* a, int size)
{
	//向下调整--建堆  O(N)
	for (int i = (size - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDown(a, size, i);
	}
 
	//如果升序建小堆,最小的数已经在堆顶,剩下的数关系打乱,需要重新建堆,建堆最好也要O(N)
	//再选出次小的,不断建堆选数,如果这样,还不如直接遍历选数!!
 
	//升序要建大堆,
	size_t end = size - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		end--;
	}
}
 
int main()
{
	int a[] = { 4,2,1,3,5,7,9,8,6};
	HeapSort(a,sizeof(a)/sizeof(int));
	for (int i = 0; i < sizeof(a) / sizeof(int); ++i)
	{
		printf("%d ", a[i]);
	}
  
	return 0;
}

1.6演示结果

总结

到此这篇关于C语言数据结构之堆排序优化算法的文章就介绍到这了,更多相关C语言堆排序优化算法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言数据结构之堆排序的优化算法

本文链接: https://www.lsjlt.com/news/146610.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言数据结构之堆排序的优化算法
    目录1.堆排序优化算法1.1建堆的时间复杂度1.1.1 向下调整建堆:O(N)1.1.2 向上调整建堆:O(N*logN)1.2堆排序的复杂度1.2.1原堆排序的时间复杂度...
    99+
    2022-11-13
  • C语言数据结构之堆排序详解
    目录1.堆的概念及结构2.堆的实现2.1 堆的向下调整算法2.2 堆的向上调整算法2.3 建堆(数组)2.4 堆排序2.5 堆排序的时间复杂度1.堆的概念及结构 如果有一个关键码的集...
    99+
    2022-11-13
  • C语言数据结构之堆、堆排序的分析及实现
    目录 1.堆的概念结构及分类1.2堆的分类1.2.1 大堆1.2.2 小堆2. 堆的主要接口3.堆的实现3.1 堆的初始化 HeapInit3.2 堆的销毁 HeapDes...
    99+
    2022-11-13
  • C语言数据结构与算法之排序总结(一)
    目录一、前言二、基本概念1.排序2.排序方法的稳定性3.内部和外部排序三、插入类排序1.直接插入排序2.折半插入排序3.希尔排序四、交换类排序1.冒泡排序2.快速排序五、总结比较一、...
    99+
    2022-11-12
  • C语言数据结构与算法之排序总结(二)
    目录一、前言二、选择类排序1.简单选择排序2.树形选择排序3.堆选择排序三、归并排序四、分配类排序1.多关键字排序2.链式基数排序五、总结归纳一、前言 之前的排序总结(一)对插入类和...
    99+
    2022-11-12
  • C语言数据结构中堆排序的分析总结
    目录一、本章重点 二、堆2.1堆的介绍(三点)2.2向上调整2.3向下调整2.4建堆(两种方式)三、堆排序一、本章重点  堆向上调整向下调整堆排序 二、堆 2.1...
    99+
    2022-11-13
  • C语言数据结构堆排序示例分析
    今天小编给大家分享一下C语言数据结构堆排序示例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。TOP.堆排序前言什么是堆排...
    99+
    2023-06-30
  • C语言数据结构二叉树之堆的实现和堆排序详解
    目录一、本章重点二、堆2.1堆的介绍2.2堆的接口实现三、堆排序一、本章重点 堆的介绍堆的接口实现堆排序 二、堆 2.1堆的介绍 一般来说,堆在物理结构上是连续的数组结构,在逻辑结构...
    99+
    2022-11-13
  • 【数据结构与算法】堆与堆排序
    目录 一.堆的实现1.堆的概念2.堆的代码实现二.堆排序的讲解 一.堆的实现 1.堆的概念 堆是一种数据结构,首先它总是一颗完全二叉树(因为堆适合表示完全二叉树),在逻辑上堆是一颗...
    99+
    2023-09-04
    php 开发语言 原力计划
  • C++超详细分析优化排序算法之堆排序
    堆排序,学习了整整一天才把这个排序彻底搞明白…… 首先第一点,堆排序是直接选择排序的一种优化排序算法。由于直接排序算法的遍历次数过多,导致直接排序算法的时...
    99+
    2023-02-09
    C++堆排序 C++优化排序
  • C语言排序算法之选择排序(直接选择排序,堆排序)
    目录前言一、直接选择排序1.1 算法思想1.2 代码实现1.3 直接选择排序的特征总结二、堆排序2.1 什么是堆?2.2 判断是否是堆2.3 向下调整算...
    99+
    2022-11-13
  • C语言数据结构与算法排序的方法有哪些
    这篇文章主要介绍“C语言数据结构与算法排序的方法有哪些”,在日常操作中,相信很多人在C语言数据结构与算法排序的方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言数据结构与算法排序的方法有哪些”的疑...
    99+
    2023-06-22
  • C语言植物大战数据结构希尔排序算法
    目录前言一、插入排序1.排序思路2.单趟排序详细图解3.整体代码4.时间复杂度(1).最坏情况下(2).最好情况下(3).基本有序情况下(重点)5.算法特点二、希尔排序1.希尔从哪个...
    99+
    2022-11-13
  • C语言数据结构经典10大排序算法刨析
    1、冒泡排序 // 冒泡排序 #include <stdlib.h> #include <stdio.h> // 采用两层循环实现的方法。 // 参数a...
    99+
    2022-11-13
  • C语言植物大战数据结构堆排序图文示例
    目录TOP.堆排序前言一、向下调整堆排序1.向下调整建堆建堆的技巧建堆思路代码2.向下调整排序调整思路排序整体代码3.时间复杂度(难点)向下建堆O(N)向下调整(N*LogN)二、向...
    99+
    2022-11-13
  • 如何进行C语言数据结构与算法中的排序总结
    这篇文章将为大家详细讲解有关如何进行C语言数据结构与算法中的排序总结,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一、前言学习目标:排序和查找密不可分,将待处理的数据按关键值大小有序排列后,...
    99+
    2023-06-22
  • Java数据结构之选择排序算法的实现与优化
    目录初识选择排序算法实现优化后的算法实现选择排序 VS 冒泡排序初识选择排序 算法思想[以升序为例]: 第一趟选择排序时,从第一个记录开始,通过n-1次关键字的比较,从第n个记录中选...
    99+
    2023-01-28
    Java实现选择排序算法 Java选择排序算法 Java选择排序
  • C语言数据结构与算法之链表(一)
    目录引言链表的相关思考链表结点结构建立链表实现插入操作完整代码引言 在存储一大波数的时候,我们通常使用的是数组,但是数组有时候又会显得不够灵活,比如下面这个例子: 有一串已经排序好的...
    99+
    2022-11-12
  • C语言数据结构与算法之链表(二)
    目录引入模拟链表介绍插入代码实现代码实现  引入 在上一节的学习中我们介绍了C语言如何实现链表,但是,在这一章,我们将抛开令人头秃的指针和结构体,我们将另外使用一种数组来实现的方式,...
    99+
    2022-11-12
  • C语言数据结构之队列算法详解
    目录一、前言二、基本概念三、顺序队列四、链队列五、循环队列六、总结与提高一、前言 队列在程序设计中经常出现,如:操作系统中的排队问题。 这篇文章主要介绍了队列的...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作