百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

「数据结构」C语言排序方法——堆排序详解

toyiye 2024-07-08 00:30 12 浏览 0 评论

堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

对于堆的操作通常需要以下3个步骤:

最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点

创建最大堆(Build Max Heap):将堆中的所有数据重新排序

堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算。

C代码实现

代码看起来比较抽象,将代码运行时数据交换的过程打印出来,然后结合二叉树的图形来分析,就会比较好理解了。 代码运行过程中数据交换过程如下:

为了方便观看这里使用二叉树图形生成软件,通过二叉树图形来观察数据交换过程。 二叉树图形生成使用的是一个在线生成网站:mshang.ca/syntree 后面所有的二叉树图形都使用此软件生成。

代码一开始首先打印出原始数据

数组元素 0 8 1 5 4 3 7 9 2 6 将这10个数据在网站上使用公式生成二叉树的图表,软件界面如下:

首先将数组从上至下按顺序排列,转换成二叉树。

公式: 0[8 [5 9[2]][4[6]]] [1[3] [7 ]]]

生成二叉树图表:

转换成二叉树之后,需要让这个无序堆变成最大堆,也就是每个堆都实现父节点的值大于任何一个子节点值。 从最后一个堆开始,依次比较父节点和子节点的值,如果子节点值大于父节点值,就需要交换。

创建最大堆: 6为最后一个子节点,所以从6开始依次和父节点比较,如果子节点大于父节点,就需要交换子节点和父节点的位置。 从设备树图形中可以看出,子节点6大于父节点4,所以需要交换子节点的父节点的位置。

公式:0[8 [5 9[2]][6[4]]] [1[3] [7 ]]]

交换 6 和4

6交换完成后,接下来依次向前比较其他子节点,6前面的节点是2,2小于父节点5,继续向前查找子节点9,子节点9大于父节点5,所以就交换9和5的位置。

公式:0[8 [9 5[2]][6[4]]] [1[3] [7 ]]]

交换9和5

接下来继续向前查找,发现子节点7大于父节点1,继续交换。

公式:0[8 [9 5[2]][6[4]]] [7[3] [1 ]]]

交换7和1

继续向前查找发现子节点9大于父节点8,交换位置。

公式:0[9 [8 5[2]][6[4]]] [7[3] [1 ]]]

交换9和8

继续比较其他节点

公式:9[0 [8 5[2]][6[4]]] [7[3] [1 ]]]

交换9和0

公式:9[8 [0 5[2]][6[4]]] [7[3] [1 ]]]

交换8和0

公式:9[8 [5 0[2]][6[4]]] [7[3] [1 ]]]

交换5和0

此时最大堆已经创建完成,此时根节点的数字9就是数组中的最大值。

代码中打印出来的数据顺序和通过二叉树图形分析出来的顺序完全一样。 此时最大堆调整已经完成了。接下来就需要开始堆排序,依次将根节点的数据存放到最后一个节点,形成一个有序堆。

堆排序(最大堆调整)

首先交换数组中第一个元素,和排序好的前一个元素位置。 此时数组中的第一个元素是9,排序完成之后最后一个元素是4,交换9和4.

公式:4[8 [5 0[2]][6[9]]] [7[3] [1 ]]]

交换9和4

交换完成后,此时最大值9所在的底部位置就成为了有序区,有序区之后就不会参与任何对比。 接下来继续调整父节点和子节点,确保父节点要大于子节点。

公式:8[4 [5 0[2]][6[9]]] [7[3] [1 ]]]

交换8和4

公式:8[6 [5 0[2]][4[9]]] [7[3] [1 ]]]

交换6和4

此时数字8称为了根节点,是目前无序区中的最大值,将8和底部区的2交换,将当前最大值8放到有序区中。

公式:2[6 [5 0[8]][4[9]]] [7[3] [1 ]]]

交换8和2

此时8已经存放到了有序区中,此后就不参与任何交换了。 此时2变为根节点后,需要再重新调整一次节点,确保父节点大于子节点。

公式:7[6 [5 0[8]][4[9]]] [2[3] [1 ]]]

交换7和2

公式:7[6 [5 0[8]][4[9]]] [3[2] [1 ]]]

交换3和2

此时数字7变为根节点,是无序区间的最大值。需要将根节点的数字移动到有序区中。

将根节点7和0交换位置。

公式:0[6 [5 7[8]][4[9]]] [3[2] [1 ]]]

交换7和0

接下来重新调整节点 公式:6[0 [5 7[8]][4[9]]] [3[2] [1 ]]]

交换6和0

公式:6[5 [0 7[8]][4[9]]] [3[2] [1 ]]]

交换5和0

此时6变为了根节点,是无序区间的最大值。

将根节点和有序区间的前一个数字交换,也就是1和6需要交换。

公式:1[5 [0 7[8]][4[9]]] [3[2] [6 ]]]

交换6和1

接下来重新调节一次节点

公式:5[1 [0 7[8]][4[9]]] [3[2] [6 ]]]

交换5和1

公式:5[4 [0 7[8]][1[9]]] [3[2] [6 ]]]

交换4和1

此时5变成的根节点,需要将5移动到有序队列中去。

接下来需要交换根节点5和无序节点2的位置

公式:2[4 [0 7[8]][1[9]]] [3[5] [6 ]]]

交换5和2

重新调整节点位置

公式:4[2 [0 7[8]][1[9]]] [3[5] [6 ]]]

交换4和2

此时4是无序列表中的最大值,需要交换4和1的位置

公式:1[2 [0 7[8]][4[9]]] [3[5] [6 ]]]

交换4和1

重新调整节点位置

公式:9[2 [0 6[7]][3[8]]] [1[4] [5 ]]]

交换3和1

此时3为无序列表中最大值,需要交换3和0的位置。

公式:0[2 [3 7[8]][4[9]]] [1[5] [6 ]]]

交换3和0

交换完成后重新调整节点位置 公式:9[0 [2 6[7]][3[8]]] [1[4] [5 ]]]

交换2和0

此时2变成了无序列表中最大值,1为有序列表的前一个值,交换2和1的位置。

公式:1[0 [3 7[8]][4[9]]] [2[5] [6 ]]]

交换2和1

此时1是根节点,无序列表中就剩0一个数字了,交换1和0。

公式:0[1 [3 7[8]][4[9]]] [2[5] [6 ]]]

交换1和0

这是0变成了根节点,而其他的所有数字都在有序列表中,无序列表中已经没有数字了,此时说明排序完成。

接下来测试一下最坏情况下数字移动情况

在测试一下最好情况下数字移动情况

可以看出最好、最坏、一般情况下数据移动的次数和方法基本都差不多。

接下来随机生成10000个数据,看看排序需要多长时间。

最后用一张动图来演示堆排序的过程

写在最后

另外,对现在我们的大多数朋友来说还是学编程技术最重要!栽一棵树最好的时间是十年前,其次是现在。对于准备学习编程的小伙伴,如果你想更好地提升你的编程核心能力(内功)不妨从现在开始!

编程学习书籍分享:

编程学习视频分享:

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

想学习C/C++编程,或者对编程感兴趣的话可以【私信】笔者领取免费学习资料哟~

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码