返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言数据结构堆排序示例分析
  • 819
分享到

C语言数据结构堆排序示例分析

2023-06-30 13:06:42 819人浏览 薄情痞子
摘要

今天小编给大家分享一下C语言数据结构堆排序示例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。TOP.堆排序前言什么是堆排

今天小编给大家分享一下C语言数据结构排序示例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

TOP.堆排序前言

什么是堆排序?假如给你下面的代码让你完善堆排序,你会怎么写?你会怎么排?

void HeapSort(int* a, int n){}int main(){int arr[] = { 4,2,7,8,5,1,0,6 };int sz = sizeof(arr) / sizoef(arr[0]);HeapSort(arr, sz);return 0;}

堆排序就是利用堆这个数据结构,对一组数据进行排序。

所以说,堆排序整体分两步完成。

第一步,建堆

第二步,进行排序

注意:以下代码针对的是对一组 数据 排升序

一、向下调整堆排序

对的,向下调整方法,是最优秀的堆排序。

不是太想介绍那种向上调整拉胯的堆排序,我们经常用的是这种优秀的向下排序。

二者区别在于建堆的方法不同。一个是向下建堆O(N),一个是向上建堆O(N*logN)。

具体证明用到了高中 简单的数列公式。

1.向下调整建堆

建堆的技巧

向下建堆也有两种情况。

建大堆

建小堆

那么到底建大堆还是小堆呢?

解释:建堆在于你是想要排升序,还是排降序。假如建的大堆,因为堆顶的数是最大的,在我们对堆 向下调整排序时,这时候每次都需要把最大的交换到堆底。所以导致最后堆的顺序是升序。

建大堆前

C语言数据结构堆排序示例分析

建大堆后

C语言数据结构堆排序示例分析

向下调整排序后

此时数组就有序了。

C语言数据结构堆排序示例分析

结论:实质是在数组上建堆。排升序建大堆,排降序建小堆。

建堆思路代码

思路:

因为叶子结点本身就是一个大堆,所以从最后一个叶子结点的父亲结点开始进行向下建堆。

这样就能够保证每次建的堆都是大堆。

注意:

注意循环结束条件,和if语句里的边界问题child + 1 < n

注意完全二叉树父子关系公式

#include <stdio.h>//交换void swap(int* x, int* y){int t = 0;t = *x;*x = *y;*y = t;}//向下调整void AdjustDown(int* a, int n, int root){int parent = root;int child = parent * 2 + 1;while (child  < n){//每次调整都需要从左右两边选出孩子最大的那个//假设坐孩子较大,选出左右孩子大的那个if (child + 1 < n && a[child + 1] > a[child]){++child;}//开始调整。if (a[child] > a[parent]){swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}//不满足就跳出,开始下次for循环调整。else{break;}}}void HeapSort(int* a, int n){//向下调整建堆int i = 0;for (i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}}int main(){int arr[] = { 4,2,7,8,5,1,0,6 };int sz = sizeof(arr) / sizeof(arr[0]);HeapSort(arr, sz);return 0;}

2.向下调整排序

调整思路

从堆底依次 和 堆顶的数据进行交换。

对交换后的 堆顶的值 进行向下调整。向下调整时请无视交换到堆底那个最大的值。

继续循环第一步和第二步,直到到正数第二个数结束。

排序整体代码
void swap(int* x, int* y){int t = 0;t = *x;*x = *y;*y = t;}void AdjustDown(int* a, int n, int root){int parent = root;int child = parent * 2 + 1;while (child  < n){//每次调整都需要从左右两边选出孩子最大的那个//假设坐孩子较大,选出左右孩子大的那个if (child + 1 < n && a[child + 1] > a[child]){++child;}//开始调整。if (a[child] > a[parent]){swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}//不满足就跳出,开始下次for循环调整。else{break;}}}void HeapSort(int* a, int n){//向下调整建堆int i = 0;for (i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}//向下调整排序int end = 0;for (end = n-1; end > 0; end--){swap(&a[0], &a[end]);//向下调整时无视最大的那个值,所以end是n-1。AdjustDown(a, end, 0);}}int main(){int arr[] = { 4,2,7,8,5,1,0,6 };int sz = sizeof(arr) / sizeof(arr[0]);HeapSort(arr, sz);return 0;}

3.时间复杂度(难点)

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

很多人的误区在于他的时间复杂度是N*Log2N。这是错误的。

时间复杂度的计算是看思想,而不是看循环猜测。

当是满二叉树,在最坏的情况下,除了最后一层,上面所有层都需要进行向下调整。

最坏情况下的调整次数 = 每层数据个数 * 向下调整次数

第一层向下调整次数是h-1,节点个数是21-1

第二层向下调整次数是h-2, 节点个数是22-1

第h-1层向下调整次数是1,节点个数是2h-1-1

所以总的调整次数为n:n = 20*(h-1) + 21 *(h-2)+&hellip; + 2h-1-1 *(1)

根据高中错位相减得到 n = 1&minus;h+21+22+&hellip;+2h&minus;2+2h&minus;1

由等比数列前n项和得到 n = 2h&minus;h&minus;1

由二叉树性质N=2h&minus;1和 h = log2(N+1) 得到 n=N&minus;log2(N+1)

大O渐进表示法为n= O(N)

向下调整(N*LogN)

需要向下调整n-1次。每次需要调整的高度为LogN,N为节点的个数,因为节点个数每次少一个。

所以n-1次调整总次数 = log2+log3+&hellip;+log(n-1)+log(n)&asymp;log(n!)

数学知识得log(n!)和nlog(n)是同阶函数。

所以向下调整排序时间复杂度为N*LogN

所以堆排序时间复杂度为:N + N*LogN

大O渐进表示法为:O(N*LogN)

总结:堆排序时间复杂度 O(N*LogN)

二、向上调整堆排序

向上调整排序和向下调整排序的唯一不同在于建堆的不同,导致二者的建堆的时间复杂度略微不同。

1.向上调整建堆

向上调整建堆时间复杂度为N*LogN.具体原因还需要经过残酷的数学计算。孩子不会啊。但是经过网上查阅资料我又找到了计算方法。如图。

C语言数据结构堆排序示例分析

根据二叉树的性质:h = Log2(N+1)

可以将T(h) = 2h * (h-2) + 2换为:

所以总体来说就是向上调整的建堆时间复杂度为O(N * LogN).

2.建堆代码

思路:从第二个元素开始,只关注前两个元素建堆,然后再依次增加元素建堆,使它一直为堆。

向上调整建堆虽然时间复杂度略高,但是代码相对于向下调整简单一点点。

void AdjustUp(int* a, int child){//先把父亲节点表示出来。int parent = (child - 1) / 2;while (child > 0){//比较孩子和父亲,开始向上调整。if (a[child] > a[parent]){swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}

以上就是“C语言数据结构堆排序示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网其他教程频道。

--结束END--

本文标题: C语言数据结构堆排序示例分析

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

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

猜你喜欢
  • C语言数据结构堆排序示例分析
    今天小编给大家分享一下C语言数据结构堆排序示例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。TOP.堆排序前言什么是堆排...
    99+
    2023-06-30
  • C语言数据结构中堆排序的分析总结
    目录一、本章重点 二、堆2.1堆的介绍(三点)2.2向上调整2.3向下调整2.4建堆(两种方式)三、堆排序一、本章重点  堆向上调整向下调整堆排序 二、堆 2.1...
    99+
    2024-04-02
  • C语言数据结构之堆、堆排序的分析及实现
    目录 1.堆的概念结构及分类1.2堆的分类1.2.1 大堆1.2.2 小堆2. 堆的主要接口3.堆的实现3.1 堆的初始化 HeapInit3.2 堆的销毁 HeapDes...
    99+
    2024-04-02
  • C语言植物大战数据结构堆排序图文示例
    目录TOP.堆排序前言一、向下调整堆排序1.向下调整建堆建堆的技巧建堆思路代码2.向下调整排序调整思路排序整体代码3.时间复杂度(难点)向下建堆O(N)向下调整(N*LogN)二、向...
    99+
    2024-04-02
  • C语言数据结构之堆排序详解
    目录1.堆的概念及结构2.堆的实现2.1 堆的向下调整算法2.2 堆的向上调整算法2.3 建堆(数组)2.4 堆排序2.5 堆排序的时间复杂度1.堆的概念及结构 如果有一个关键码的集...
    99+
    2024-04-02
  • C语言数据结构之堆排序的优化算法
    目录1.堆排序优化算法1.1建堆的时间复杂度1.1.1 向下调整建堆:O(N)1.1.2 向上调整建堆:O(N*logN)1.2堆排序的复杂度1.2.1原堆排序的时间复杂度...
    99+
    2024-04-02
  • Go数据结构之堆排序示例详解
    目录堆排序堆排序过程动画显示开始堆排序代码实现总结堆排序 堆排序是一种树形选择排序算法。 简单选择排序算法每次选择一个关键字最小的记录需要 O(n) 的时间,而堆排序选择一个关键字最...
    99+
    2024-04-02
  • python数据结构堆的示例分析
    小编给大家分享一下python数据结构堆的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、说明堆是用数据结构来实现的一种算法:树,数组均可。堆本身是一棵完全二叉树。2、特点最大堆:所有父节点的值大于子节点的值最小...
    99+
    2023-06-15
  • C语言数据结构经典10大排序算法实例分析
    今天小编给大家分享一下C语言数据结构经典10大排序算法实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1、冒泡排序//...
    99+
    2023-06-29
  • C语言数据结构之绪论的示例分析
    小编给大家分享一下C语言数据结构之绪论的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!绪论什么是数据结构?不同于计算机操作培训,注意与程序设计的区别。Ex...
    99+
    2023-06-20
  • C语言数据结构二叉树之堆的实现和堆排序详解
    目录一、本章重点二、堆2.1堆的介绍2.2堆的接口实现三、堆排序一、本章重点 堆的介绍堆的接口实现堆排序 二、堆 2.1堆的介绍 一般来说,堆在物理结构上是连续的数组结构,在逻辑结构...
    99+
    2024-04-02
  • C语言结构化程序设计的示例分析
    这篇文章主要为大家展示了“C语言结构化程序设计的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言结构化程序设计的示例分析”这篇文章吧。C语言是结构化的程序设计语言!结构有三大类:顺序...
    99+
    2023-06-20
  • 【数据结构】选择排序 & 堆排序(二)
    目录 一,选择排序 1,基本思想 2, 基本思路 3,思路实现 二,堆排序 1,直接选择排序的特性总结: 2,思路实现 3,源代码 最后祝大家国庆快乐! 一,选择排序 1,基本思想 每一次从待排序的数据元素中选出最小(或最大)的一个...
    99+
    2023-10-18
    排序算法 算法 数据结构 c语言 开发语言
  • C语言植物大战数据结构快速排序图文示例
    目录快速排序一、经典1962年Hoare法1.单趟排序2.递归左半区间和右半区间3.代码实现二、填坑法(了解)1.单趟思路2.代码实现三、双指针法(最佳方法)1.单趟排序2.具体思路...
    99+
    2024-04-02
  • 【数据结构与算法】堆与堆排序
    目录 一.堆的实现1.堆的概念2.堆的代码实现二.堆排序的讲解 一.堆的实现 1.堆的概念 堆是一种数据结构,首先它总是一颗完全二叉树(因为堆适合表示完全二叉树),在逻辑上堆是一颗...
    99+
    2023-09-04
    php 开发语言 原力计划
  • Go语言数据结构之希尔排序示例详解
    目录希尔排序算法思想图解算法Go 代码实现:总结希尔排序 在插入排序中,在待排序序列的记录个数比较少,而且基本有序,则排序的效率较高。 1959 年,Donald ...
    99+
    2024-04-02
  • Go语言数据结构之选择排序示例详解
    目录选择排序动画演示Go 代码实现总结选择排序 选择排序(selection sort)是一种原地(in-place)排序算法,适用于数据量较少的情况。由于选择操作是基于键...
    99+
    2024-04-02
  • Go语言数据结构之插入排序示例详解
    目录插入排序动画演示Go 代码实现总结插入排序 插入排序,英文名(insertion sort)是一种简单且有效的比较排序算法。 思想: 在每次迭代过程中算法随机地从输入序...
    99+
    2024-04-02
  • C语言中冒泡排序的示例分析
    这篇文章给大家分享的是有关C语言中冒泡排序的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。(壹)冒泡排序1.1冒泡排序的设计冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排...
    99+
    2023-06-29
  • C语言结构体指针的示例分析
    这篇文章给大家分享的是有关C语言结构体指针的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。写结构体指针前,先说一下 . 号和 -> 的区别记得当初刚学C语言的...
    99+
    2023-06-20
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作