返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >【数据结构】-向上调整算法和向下调整算法
  • 509
分享到

【数据结构】-向上调整算法和向下调整算法

数据结构php开发语言 2023-09-17 13:09:29 509人浏览 薄情痞子
摘要

作者:小树苗渴望变成参天大树 作者宣言:认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! 堆 前言一、堆的

作者:小树苗渴望变成参天大树
作者宣言:认真写好每一篇博客
作者gitee:gitee
在这里插入图片描述
如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧!


前言

今天我们来堆,堆是建立再有二叉树基础的前提下去学习的,采用的是二叉树的顺序存储方式,所以结构类似于满二叉树,会介绍堆的概念,以及模拟一个堆出来,本篇知识量有一点大,希望读者可以耐心的阅读下去,并且真正学会堆


一、堆的概念及结构

如果有一个关键码的集合K = { , , ,…, },把它的所有元素按完全二叉树的顺存储方式存储在一个一维数组中,并满足: <= 且 <= ( >= 且 >= ) i = 0,1,2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

堆的性质:
1.堆中某个节点的值总是不大于或不小于其父节点的值;
2.堆总是一棵完全二叉树。
3.堆顶一定是整个堆中最大或者最小的数据

我们只需要看堆的性质即可
我们来看一下两种类型的堆
在这里插入图片描述

看到现在我们要掌握什么是堆,什么是大根堆,什么是小根堆,以及怎么通过堆写成数组的形式,怎么通过数组来写成堆的形式

注意:堆里面的元素如果都相等的话,即可以看成大根堆,也可以看成小根堆

二、堆的创建(以大根堆为例)

我们刚才说过对于堆我们采取数组的方式来存储,还要满足可以往堆里面插入和删除数据时必须还得是堆的情况,我们采取顺序表的创建方式来创建堆

typedef int HPDataType;typedef struct Heap{HPDataType* a;//定义一个数组int size;//数组里面的有效数据个数int capacity;//此时数组容量大小}Heap;

初始化和顺序表初始化一样:

void HPInit(Heap* PHP){php->a = (HPDataType*)malloc(sizeof(HPDataType) * 4);if (php->a == NULL){perror("malloc:");return;}php->size = 0;php->capacity = 4;}

我们重点来介绍堆的插入和删除

三、堆的插入

我们插入数组的树必须保证原数组依然是堆,这就很有难度,我们先来看图讲解:
在这里插入图片描述
我们采取的是向上调整算法,肯定是先插入左孩子,再插入右孩子,所以插入的是右孩子不必考虑左孩子的值是否比父亲大等情况,我们只需要把插入的孩子和父亲比较就好了,当parent<0就结束,没有交换的时候表示已经是堆了,因为你再插入的之前他就是一个堆了

我们来看向上调整算法代码:

void Swap(HPDataType* p1, HPDataType* p2){HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;}void AdjustUp(HPDataType* a, int child)//传入的数组和插入的孩子再数组的下标{assert(a);int parent = (child - 1) / 2;//找到父亲结点对应的下标while (child > 0){if (a[parent] < a[child])//以大根堆为例,小根堆换一下符号即可{Swap(&a[parent], &a[child]);//交换child = parent;parent = (child - 1) / 2;//迭代}else{break;}}}

因为都是一步步的向上进行调整,所有就叫向上调整算法

我们看堆的插入:

void HeapPush(Heap* php, HPDataType x){assert(php);if (php->size == php->capacity){HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * 2 * php->capacity);if (tmp == NULL){perror("realloc:");return;}else{php->a = tmp;php->capacity *= 2;}}php->a[php->size++] = x;//先插入,再把数组弄成堆的形式AdjustUp(php->a, php->size - 1);//向上调整算法}

四、堆的删除

我们来想一下,堆的删除,应该还是删除那一个数据,是堆头还是堆尾,我们可以来想想,如果删除堆尾,有什么意义,即不一定是最大的数据,也不是最小的数据,没有什么意义,所以我们选择删除堆头的数据,那我们怎么去删除呢

有的人会想,再顺序表的时候,我们进行头删的时候,把前面的数据直接往前面挪一位,所以我们再堆的时候可不可以也这样搞,我们来画图看看:
在这里插入图片描述

我们发现采取挪数据的方式并不可取,父亲与孩子的关系全部乱了,那我们应该怎么去解决删数据的问题呢??

我们想到一种方法,因为插入数据是在尾部插入,插入之前是堆,不影响,那我们再删除的时候再从尾部删除不就可以了,但是我要删除的数据是堆顶的数据啊,怎么删除尾部的呢,我们可以交换一下,那交换了这个堆可能就不是堆了,但是堆里面的结点的那个对应关系是不是没有破坏,我们重新调整就好了
来看图:
在这里插入图片描述
我们看到我们采取的向下天正算法,把交换好的数据重新调整成堆,我们来直观的看一下向下调整算法的代码

void Swap(HPDataType* p1, HPDataType* p2){HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;}void AdjustDown(HPDataType* a, int n, int parent){int child = parent * 2 + 1;//假设左孩子大while (child<n){if (child + 1 < n && a[child] < a[child + 1]){child += 1;}if (a[parent] < a[child]){Swap(&a[parent], &a[child]);parent = child;child = parent * 2 + 1;}else{break;}}}

不会的可以走读一下代码看看是怎么实现的
我们来看一下删除的完整代码:

void HeapPop(Heap* php){assert(php);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size, 0);//因为都是从堆顶调整,所以parent传的就是0}

注意:向上调整算法和向下调整算法都有一个前提条件,被调整的那个结点,左右子树都必须是堆

对于堆的两款大骨头我们几乎啃完了,接下来大部分都是顺序表玩生下来的操作了

五、堆顶的元素

HPDataType* HeapTop(Heap* php){assert(php);return php->a[0];}

六、判断堆是否为空

bool HeapEmtpy(Heap* php){assert(php);return php->size == 0;}

七、堆里有多少元素

int HeapSize(Heap* php){assert(php);return php->size;}

八、代码测试

int main(){Heap php;HPInit(&php);HeapPush(&php,1);HeapPush(&php, 2);HeapPush(&php, 34);HeapPush(&php, 4);HeapPush(&php, 23);HeapPush(&php, 16);HeapPush(&php, 7);while (!HeapEmtpy(&php)){printf("%d ", HeapTop(&php));HeapPop(&php);}}

在这里插入图片描述
我们看到我们手动模拟出来一个堆了,相信大家学到这里对堆有了不一样的理解

完整代码:

#include"Heap.h"void HPInit(Heap* php){php->a = (HPDataType*)malloc(sizeof(HPDataType) * 4);if (php->a == NULL){perror("malloc:");return;}php->size = 0;php->capacity = 4;}void Swap(HPDataType* p1, HPDataType* p2){HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;}void AdjustUp(HPDataType* a, int child){assert(a);int parent = (child - 1) / 2;while (child > 0){if (a[parent] < a[child]){Swap(&a[parent], &a[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}void HeapPush(Heap* php, HPDataType x){assert(php);if (php->size == php->capacity){HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * 2 * php->capacity);if (tmp == NULL){perror("realloc:");return;}else{php->a = tmp;php->capacity *= 2;}}php->a[php->size++] = x;AdjustUp(php->a, php->size - 1);//向上调整算法}void AdjustDown(HPDataType* a, int n, int parent){int child = parent * 2 + 1;//假设左孩子大while (child<n){if (child + 1 < n && a[child] < a[child + 1]){child += 1;}if (a[parent] < a[child]){Swap(&a[parent], &a[child]);parent = child;child = parent * 2 + 1;}else{break;}}}void HeapPop(Heap* php){assert(php);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size, 0);}HPDataType* HeapTop(Heap* php){assert(php);return php->a[0];}bool HeapEmtpy(Heap* php){assert(php);return php->size == 0;}int HeapSize(Heap* php){assert(php);return php->size;}#include#include#include#includetypedef int HPDataType;typedef struct Heap{HPDataType* a;int size;int capacity;}Heap;void HPInit(Heap* php);void HeapPush(Heap* php, HPDataType x);void HeapPop(Heap* php);HPDataType* HeapTop(Heap* php);bool HeapEmtpy(Heap* php);int HeapSize(Heap* php);

来源地址:https://blog.csdn.net/qq_69369227/article/details/129758954

--结束END--

本文标题: 【数据结构】-向上调整算法和向下调整算法

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

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

猜你喜欢
  • 【数据结构】-向上调整算法和向下调整算法
    作者:小树苗渴望变成参天大树 作者宣言:认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! 堆 前言一、堆的...
    99+
    2023-09-17
    数据结构 php 开发语言
  • Java数据结构中堆的向下和向上调整解析
    目录一、关于堆1.堆的概念2.堆的性质3.堆的存储方式二、堆的创建1.堆向下调整2.堆的创建三、向上调整一、关于堆 JDK1.8中的PriortyQueue(优先级队列)底层使用了堆...
    99+
    2024-04-02
  • Java中堆的向下和向上调整示例分析
    这篇文章主要介绍Java中堆的向下和向上调整示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、关于堆JDK1.8中的PriortyQueue(优先级队列)底层使用了堆的数据结构,而堆实际就是在完全二叉树的基础...
    99+
    2023-06-25
  • MySQL数据库中怎么调整磁盘IO调度算法
    MySQL数据库中怎么调整磁盘IO调度算法,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 查看当前系统支持的磁盘...
    99+
    2024-04-02
  • c语言实现向上取整计算方法
    目录c语言向上取整计算c语言向上取整的一点技巧c语言向上取整计算 用整数N 除以 M,要求向上取整数 int n = (N + M -1) / M ; 简化后就是: int n= (...
    99+
    2024-04-02
  • TypeScript调整数组元素顺序算法
    目录前言实现思路实现代码代码的可扩展性测试用例示例代码总结前言 有一个整数数组,我们想按照特定规则对数组中的元素进行排序,比如:数组中的所有奇数位于数组的前半部分。 本文将带大家实现...
    99+
    2024-04-02
  • 数据结构和算法:算法复杂度
    我们开始了算法复杂度的学习,本期教程我们学习后半段。复杂度只考虑操作数目的一个数量级(忽略了其他的组分),这是一种近似。为了表示这种近似,我们使用一个特定的符号,就是著名的 大 O 符号。大 O 符号(Big O notation...
    99+
    2023-06-01
  • Java数据结构与算法学习之双向链表
    目录双向链表的储存结构示意图双向链表的初始化结构1.双向链表的结点2.双向链表的头结点3.总代码双向链表中的指定文件插入元素 1.插入的为第一个位置2.其他位置插入总代码双向链表的删...
    99+
    2024-04-02
  • 带你了解Java数据结构和算法之无权无向图
    目录1、图的定义①、邻接:②、路径:③、连通图和非连通图:④、有向图和无向图:⑤、有权图和无权图:2、在程序中表示图①、顶点:②、边:3、搜索①、深度优先搜索(DFS)②、广度优先搜...
    99+
    2024-04-02
  • 在windows8中调整屏幕显示方向的方法
    适用范围: Windows 8 消费者预览版 操作步骤: 1、在桌面空白处点击鼠标右键,在弹出菜单中选择“屏幕分辨率”。如下图所示: 2、在“方向”栏,使用...
    99+
    2022-06-04
    屏幕 方向 方法
  • Java 数据结构与算法系列精讲之单向链表
    目录概述链表单向链表单向链表实现Node 类add 方法remove 方法get 方法set 方法contain 方法main完整代码概述 从今天开始, 小白我将带大家开启 Jave...
    99+
    2024-04-02
  • java数据结构和算法之马踏棋盘算法
    本文实例为大家分享了java实现算法之马踏棋盘的具体代码,供大家参考,具体内容如下 一、马踏棋盘算法介绍 马踏棋盘算法也被称为骑士周游问题将马随机放在国际象棋的8×8棋盘...
    99+
    2024-04-02
  • PHP中的算法和数据结构
    PHP是一种广泛应用的开发语言,常用于Web应用程序的开发。然而,Web应用程序往往需要处理大量的数据,包括数据的处理、存储和查询等等,因此,在PHP中应用算法和数据结构是非常关键的技术。算法是一种在计算机编程中用来解决问题的通用方法。在编...
    99+
    2023-05-25
    PHP算法 PHP数据结构 算法实现(PHP)
  • 了解PHP数据结构和算法
    PHP是一种广泛应用于Web开发的脚本语言,且在建立动态网站上表现得越来越好。在Web开发中,数据结构和算法的重要性并不低于其他编程范畴,其对于程序运行效率的影响尤为显著。尤其是在涉及大量数据存储和处理,或者对程序性能要求较高的场景下,数据...
    99+
    2023-05-24
    PHP算法 PHP数据结构 数据算法
  • 如何调整2000运行中的数据库结构
    如何调整2000运行中的数据库结构,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。开发过程中的数据库结构结构,不可避免的会需要反复的修改。最麻烦...
    99+
    2024-04-02
  • JavaScript数据结构与算法
    目录前言数据结构常见的数据结构算法算法的特征算法的目标总结前言 数据结构与算法这个词相信大家都听过、了解过、学过,那为什么要学习数据结构与算法呢?我感觉有以下两个原因: 为了一个比较...
    99+
    2024-04-02
  • Java数据结构与算法之栈(动力节点Java学院整理)
    stack,中文翻译为堆栈,其实指的是栈,heap,堆。这里讲的是数据结构的栈,不是内存分配里面的堆和栈。栈是先进后出的数据的结构,好比你碟子一个一个堆起来,最后放的那个是堆在最上面的。队列就是排队买苹果,先去的那个可以先买。栈public...
    99+
    2023-05-31
    java 数据结构 算法
  • 数据结构与算法之手撕排序算法
    目录前言为什么要学习排序算法?一.排序的概念及其应用1.1排序的概念1.2排序运用1.3 常见的排序算法二.排序算法分类1.插入排序1.1基本思想:1.2直接插入排序:1.3 希尔排...
    99+
    2023-05-16
    Java数据结构与算法 Java排序算法 数据结构与算法 排序算法
  • java数据结构基础:算法
    目录数据结构和算法关系高斯求和算法定义算法的特性算法设计的要求算法效率的度量方法函数的渐进增长总结数据结构和算法关系 虽然这个标题起的叫数据结构,但是我却总结算法。。。我不是没事找抽...
    99+
    2024-04-02
  • python数据结构与算法(3)
    Python内置类型性能分析 timeit模块timeit模块可以⽤来测试⼀⼩段Python代码的执⾏速度。class timeit.Timer(stmt='pass', setup='pass', ...
    99+
    2023-01-31
    数据结构 算法 python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作