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

数据结构——堆(数据结构堆排序)

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

数据结构 --- 堆

一.堆的概念与结构

堆首先是一个二叉树,并且是一个特殊完全二叉树。对于完全二叉树的概念如果还不清楚,欢迎看我之前的一篇文章<<数据结构-二叉树>>。这里我们直接来理解堆的概念。

上面提到的堆是一种特殊的完全二叉树,怎么个特殊法呢?对于这颗给定的完全二叉树中任意给定节点都要满足堆属性:

  • 其值比它的子节点的值都要大,并且根节点的值比其它节点的值都要大, 这种完全二叉树称为最大堆属性。
  • 其值比它的子节点的值都要小,并且根节点的值比其它节点的值都要小, 这种完全二叉树称为最小堆属性。

如图所示,最大堆的最小堆示例。

我们也可以将上面具有堆属性的完全二叉树称为二叉堆。

二.堆的存储与构建

一般情况下,可以用链表或者数组存储。由于堆的是一颗完全二叉树,所以用数组存储堆,访问起来非常方便,所以当给定一个有初值的数组,我们可以首先将其表示成一颗完全二叉树,然后再进行调整,使其成为一个最大堆或者最小堆。

下面具体描述如何从一个一维数组构建出一个最大堆(最小堆同理)。

假设有一个n个元素的数组A如下图(图中画了6个元素作为示例)。

  1. 首先将数组A表示成一颗完全二叉树

这里简述一下,如何将数组表示成(看成)一颗完全二叉树的。这是由于完全二叉树的特点决定的。由于完全二叉树除了最下层元素可以不满,其它层元素都是满的,而且最下层元素是从左向右排列的。也就是说,缺少的只能是最右边的元素,基于此,用可以一维数组表示一颗完全二叉树:

  • 若A[i]表示父节点,那么其子节点为A[2*i+1]和A[2*i+2], 其中2*i+1 和 2*i+2必须<= A的长度
  • 若A[k]表示子节点,那么A[(k-1)/2]即是A[k]的父节点

根据以上两点,我们就可以将该一维数组看成一颗完全二叉树。比如根节点A[0]=1 那么 A[2*0+1] = A[1] = 6, 即6是1的左孩子节点。再比如A[5]=7, 那么7的父节点为A[(5-1)/2] = A[2] = 9, 即7的父节点是9。 对照上图,可以看到完全正确。

  1. 从第一个非叶子节点索引为n/2 – 1 开始. 这里n表示元素个数。
  1. 将当前节点i设置为最大节点largestNodeIndex。
  2. 比较当前节点i的值A[i]左孩子节点A[2*i+1] 的值, 如何 A[2*i+1] > A[i],设置2*i+1 为最大节点largestNodeIndex。

比较A[largestNodeIndex] 和 当前节点的右孩子A[2*i + 2]的值,如果A[2*i + 2] > A[largestNodeIndex] 则设置2*i + 2为最大节点largestNodeIndex。

  1. 交换当前节点A[i]和A[largestNodeIndex]。
  1. 重复#3到#6直到最大堆构建完成。

至此最大堆构建完成。实现的python代码如下:

def heapify(arr, n, i):

largestNodeIndex= i

l = 2 * i + 1

r = 2 * i + 2


if l < n and arr[i] < arr[l]:

largestNodeIndex= l


if r < n and arr[largest] < arr[r]:

largestNodeIndex= r


if largest != i:

arr[i],arr[largestNodeIndex] = arr[largestNodeIndex],arr[i]

heapify(arr, n, largestNodeIndex)

三.如何向堆中插入元素

上面我们谈了堆的构建,现在我们来看如何向堆内插入一个元素。向堆内插入元素,我可以将该元素插入到堆的尾部,然后再根据情况将元素向上调整可以认为是堆的一次构建。这里依然以最大堆插入为例,具体图示描述如下:

  1. 将元素插入到堆的尾部
  1. 将元素进行向上调整,直到全部元素满足堆的性质。

插入过程的python代码实现如下:

def insert(array, newNum):

size = len(array)

if size == 0:

array.append(newNum)

else:

array.append(newNum);

for i in range((size//2)-1, -1, -1):

heapify(array, size, i)

四. 如何从堆中删除一个元素

这里依然以最大堆删除为例。删除的步骤如下:

  1. 选择要删除的元素,比如下图所示,要删除6。
  1. 将其与最后一个元素进行交换。
  1. 删除最后一个元素。
  1. 重新对删除后的堆进行调整,直到全部元素满足最大堆的性质。

删除过程的Python代码实现如下:

def deleteNode(array, num):

size = len(array)

i = 0

for i in range(0, size):

if num == array[i]:

break


array[i], array[size-1] = array[size-1], array[i]

array.remove(num)


for i in range((len(array)//2)-1, -1, -1):

heapify(array, len(array), i)

由于堆的特性,在最大堆中根节点就是最大元素,而在最小堆中,根节点就是最小元素,所以在最大堆查找最大元素和在最小堆查找最小元素十分方便。

相关推荐

为何越来越多的编程语言使用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)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码