首页
学习
活动
专区
圈层
工具
发布

数据结构【顺序结构二叉树:堆】(1)

⽗结点/双亲结点:若⼀个结点含有⼦结点,则这个结点称为其⼦结点的⽗结点;如上图:A是B的⽗ 结点 ⼦结点/孩⼦结点:⼀个结点含有的⼦树的根结点称为该结点的⼦结点;如上图:B是A的孩⼦结点 结点的度:⼀个结点有...对于深度为 K 的,有 n 个 结点的⼆叉树,当且仅当其每⼀个结点都与深度为K的满⼆叉树中编号从 1 ⾄ n 的结点⼀⼀对应时称 之为完全⼆叉树。要注意的是满⼆叉树是⼀种特殊的完全⼆叉树。...第三步:判断pr下标打印zuo下标进行交换,然后把zuo给pr,让zuo找下一个左孩子。...第二步:size-1就相当于把最后一个的数据删除。 第三步:向下调整。...向上调整算法建堆和向下调整算法建堆,都能建堆,随便选择一个就行了。 我们可以看到堆已经弄好了 开始排序 第一步:size-1就是最后一个数值的下标,赋值给i。 第二步:堆顶和最后一个数值进行交换。

32210

一文彻底搞清楚二叉树和堆:从概念到存储结构解析

例如;某家庭成员关系图如下:奶奶(用A表示)有三个孩子B、C、D;大儿子B有两个孩子E和F;二儿子C有一个孩子G;三儿子有两个孩子H和I;孙子E有一个孩子J;孙子G有两个孩子K和L.这个家庭关系可以用一棵树来表示.... 2️⃣孩子表示法:孩子表示法是把树中每个结点的孩子结点排列起来,构成一个线性表.由于每个结点的孩子个数不确定,所以通常采用单链表作为存储结构,称为孩子链表.n个结点有n个孩子链表(其中叶子结点的孩子链表为空表...),而n个结点的数据和n个孩子链表头指针构成一个顺序表,用一个一维数组来表示. 3️⃣孩子兄弟表示法:孩子兄弟表示法又称二叉链表表示法,即以二叉链表作为树的存储结构.链表中的每个结点有两个链域,...分别指向该结点的第一个孩子结点和下一个兄弟结点....− 1,则它就是满⼆叉树. 2.2.2完全二叉树 完全⼆叉树是效率很⾼的数据结构,完全⼆叉树是由满⼆叉树⽽引出来的.对于深度为 K 的,有 n 个结点的⼆叉树,当且仅当其每⼀个结点都与深度为K的满

30310
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    数据结构与算法——堆

    对于深度为 K 的(有K层),有 n 个结点的⼆叉树,当且仅当其每⼀个结点都与深度为K的满⼆叉树中编号从 1 ⾄ n 的结点⼀⼀对应时称之为完全⼆叉树。要注意的是满⼆叉树是⼀种特殊的完全⼆叉树。...,然后删除最后一个结点,因为是大堆,运用向下调整法又找剩余数据中的最大值,直到所有的数据出堆),那这就是用用堆排序的方法吗?...= (n - 1 - 1) / 2; i >= 0; i--) //初始值就是最后一棵子树,n-1为最后一个子结点,再减1除2就是其父结点也就最后一棵子树开始 { AdjustDown(arr,...(int i = (n - 1 - 1) / 2; i >= 0; i--) //初始值就是最后一棵子树,n-1为最后一个子结点,再减1除2就是其父结点也就最后一棵子树开始 { AdjustDown...fin 是文件指针,指向要写入的文件。 "%d\n" 是格式字符串,表示以十进制整数格式写入数据,后面跟一个换行符。 x 是要写入的整数值。

    14610

    怪兽电力公司的翻硬币游戏

    怪兽电力公司研制了一套“孩卧溜”系统(即“孩子卧室溜入”系统)给怪兽世界供电——在夜深人静的时候,一个个怪兽惊吓师们通过该系统各自从孩子们的卧室衣橱门溜到床头,把孩子们吓得大叫,然后该系统就能把孩子受到惊吓所发出的尖叫声变成电流来供电...怪兽们普遍认为人类孩子周身充满剧毒,碰一下就能致命,所以惊吓师是一个高风险的职位。另外人类孩子的胆子似乎越来越大,这种发电方式难以为继。...我作为用户也计时,从业务分析师翻第1枚开始,到我收到第1枚和最后1枚为止。”独眼豆说。 “第1枚和最后1枚?如果是20枚一起传给你,那岂不是两个时间是一样的?”三眼怪转着3个眼珠说。...独眼豆让众怪围拢过来坐在一起看他夹子上的表格,“先看最后一列,当20枚一批传递时,用户收到第1枚和第20枚都是103秒;当10枚一个批次传递时,用户收到第1枚需要等50秒,收到20枚需要等65秒;当1枚一个批次时...我问大家,用户同样是收到这20枚硬币,为什么1枚一个批次会比20枚一个批次要快近1倍?” “因为20枚一个批次,当雪怪在翻时,后面的怪兽都在等嘛!”蓝毛怪说。

    91420

    树和二叉树

    当 n > 1 时,其余结点可分为 m(m > 0)个互不相交的有限集T1、T2,… ,Tm,其中每一个集合本身又是一颗树,并且称为根的 子树(SubTree)。...二叉树的性质 image.png 完全二叉树:深度为k的具有n个结点的二叉树,当且仅当其每一个结点都与深度为k的 满二叉树中编号 为1 ~ n的结点一一对应时, 称之为完全二叉树。...满二叉树 一定是 完全二叉树 完全二叉树 不一定是 满二叉树 注:在满二叉树中,从最后一个结点开始,连续 去掉 任意 个结点,即是一棵完全二叉树。(一定是连续的去掉!!!)...如果 2i > n,则结点 i 为叶子结点,无左孩子;否则,其 左孩子是结点 2i。 如果 2i + 1 > n,则结点 i 无右孩子;否则,其右孩子是结点 2i + 1。...,去掉原来右孩线 森林变二叉树:树变二叉跟相连 二叉树变森林:去掉全部右孩线,孤立二叉再还原 哈夫曼树的基本概念 路径:从树中一个结点到另一个结点之间的分支构成这两个结点间的路径。

    59730

    数据结构篇-树与森林

    目录 树的存储结构 树的逻辑结构 双亲表示法(顺序存储) 孩字表示法 (顺序+链式存储) 孩子兄弟表示法(链式存储) 森林 树的遍历 树的先根遍历(深度优先遍历) 树的后根遍历(树的深度优先遍历) 树的层序遍历...在任意- - 棵非空树中应满足: 1)有且仅有一个特定的称为根的结点。 2)当n>1时,其余结点可分为m (m>0)个互不相交的有限集合T1, 2.... ...struct CTNode *next; //下一个孩子 }CTBox; typedef struct { CTBox nodes[MAX_TREE_SIZE]; int n,r; /...; //数据域 struct CSDode *firstchild ,*nextsibling; //第一个孩子和右兄弟指针 }CSDode ,*CSTree...; ---- 森林 森林是m(m>=0)棵互不相交的树集合  森林中各个树的根结点之间是为兄弟关系 在二叉树中,如果是兄弟关系就在右边,如果是孩子就在左边 ,本质上,用二叉链表存储森林 树的遍历

    55220

    【初阶数据结构和算法】初识树与二叉树的概念以及堆和完全二叉树之间的关系

    ,不满足刚刚讲的树的最后一个特点,所以不构成真正的树形结构 2.树的相关术语 ⽗结点/双亲结点:若⼀个结点含有⼦结点,则这个结点称为其⼦结点的⽗结点;如上图:A是B的父结点/双亲节点 ⼦结点/孩⼦结点:...⼀个结点含有的⼦树的根结点称为该结点的⼦结点;如上图:B是A的孩⼦结点 结点的度:⼀个结点有⼏个孩⼦,他的度就是多少;⽐如A的度为3,B的度为2,K的度为0 树的度:⼀棵树中,度最⼤的结点的度称为树的度...对于深度为K的,有n个结点的⼆叉树,当且仅当其每⼀个结点都与深度为K的满⼆叉树中编号从1⾄n的结点⼀⼀对应时称之为完全⼆叉树    也就是说完全二叉树就是除了最后一层,其它层次的节点个数都达到最大,而满二叉树则要求不仅其它层次的节点个数都达到最大...,最后一层的节点个数也要达到最大,所以满⼆叉树是⼀种特殊的完全⼆叉树,我们画一个完全二叉树看看: 二叉树的性质(由满二叉树特点推导) 如果根节点是二叉树的第1层,那么一颗非空二叉树中的第k层最多有2k...2k + 1,否则i无左孩子 (3)如果2k + 2 孩子下标为2k + 2,否则i无右孩子    这里特别说明一下,上面总结的第三点的特性也适用于普通完全二叉树,普通完全二叉树中一个节点的父节点

    28210

    数据结构-二叉树_堆

    ; 如上图:B是A的孩⼦结点 结点的度:⼀个结点有⼏个孩⼦,他的度就是多少;⽐如A的度为6,F的度为2,K的度为0 树的度:⼀棵树中,最⼤的结点的度称为树的度; 如上图:树的度为 6 叶⼦结点/终端结点...对于深度为 K 的,有 n 个 结点的⼆叉树,当且仅当其每⼀个结点都与深度为K的满⼆叉树中编号从 1 ⾄ n 的结点⼀⼀对应时称 之为完全⼆叉树。要注意的是满⼆叉树是⼀种特殊的完全⼆叉树。...2.3 ⼆叉树存储结构 2.3.1 顺序结构 无非就创建一个数组,挨个存 二叉树的数据,根节点无疑是0,然后他的两个孩子节点就是1和2,1的两个孩子节点就是4和5,以此类推。...2.3.2 链式结构 链式结构更容易想象到,就是每个节点有两个指向,一个指向左孩子,一个指向右孩子,然后每个节点都存储数据。 3....free(php->arr); php->arr = NULL; php->size = php->capacity = 0; } 3.2.2 向下调整算法 就是在删除堆顶的时候,将堆顶与最后一个元素进行交换

    22810

    【数据结构】堆和二叉树详解——上

    我们可以根据上面二叉树的真实的样子来画出数据结构中的二叉树的样子: 通过上图我们可以得到二叉树的几个特点: ⼆叉树不存在度大于 2 的结点 即要么有一个孩子或两个孩子 要么没有。...对于深度为 K 的,有 n 个 结点的⼆叉树,当且仅当其每⼀个结点都与深度为K的满⼆叉树中编号从 1 ⾄ n 的结点⼀⼀对应时称 之为完全⼆叉树。要注意的是满⼆叉树是⼀种特殊的完全⼆叉树。...2,链式存储 ⼆叉树的链式存储结构是指使用一个链表来表示一颗二叉树,链表包括三个部分一个数据和两个指针,分别指向左孩子和右孩子。这样每一个二叉树每一个结点都是独立的空间不会再有空间浪费。...若 2i+2孩⼦序号: 2i+2 , 2i+2>=n 否则⽆右孩⼦ 3.2堆的实现 首先要想实现堆就要先定义一个堆结构: //定义堆 底层使用数组 typedef int...所以直接从尾部去删除是不好的,但我们可以换一个方式,将想删除的那个数据与最后一个数据交换然后再直接尾删这样就能达到时间复杂度为O(1)。

    20310

    初识数据结构——二叉树从基础概念到实践应用

    关键特点: 有且仅有一个根节点,没有前驱节点 除根节点外,其余节点被分成M(M>0)个互不相交的子树 树是递归定义的 重要术语: 结点的度:一个结点含有子树的个数 树的度:树中所有结点度的最大值...第一个孩子引用 Node nextBrother; // 下一个兄弟引用 } 二、二叉树详解 2.1 二叉树概念 二叉树是结点的一个有限集合,该集合: 或者为空 或者由一个根节点加上两棵分别称为左子树和右子树的二叉树组成...层数为K,结点总数是2^K-1 完全二叉树:深度为K,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从0至n-1的结点一一对应 2.3 二叉树的性质 非空二叉树的第i层最多有2...Node left; // 左孩子引用,常常代表左孩⼦为根的整棵左⼦树 Node right; // 右孩子引用,常常代表右孩⼦为根的整棵右⼦树 } // 孩子双亲表示法 class...Node { int val; Node left; // 左孩子引用,常常代表左孩⼦为根的整棵左⼦树 Node right; // 右孩子引用,常常代表右孩⼦为根的整棵右

    24610

    数据结构与算法 -树和森林

    孩子链表表示法 树中每个结点的孩子串成一个单链表,数组元素存储结点本身的信息和该结点的孩子链表的头指针。 ?...孩子兄弟链表表示法 树中的每一个节点的左指针域指向该节点的第一个孩子结点,右指针域指向该结点的下一个兄弟结点。 ? 另外也可以用下面这种表现形式,意义是一样的。 ?...将转换得到的各棵二叉树的根结点看做是兄弟连接起来。 ? 最终将多个子树转化为二叉树,二叉树每个结点的左子树是孩子,右子树是兄弟。 3. 二叉树转化为一般树 (1). 从根结点起; (2)....该结点 左孩 和 左孩右枝上的结点依次作为该结点孩子; (3). 重复第1步。 ? 以下是将多棵树转化成的二叉树还原成一般树的过程。 ? 树和森林的遍历 1. 树的遍历 (1)....后序遍历:先依次后序遍历每棵子树,最后访问根结点。 (3). 层次遍历:从根结点开始,从下至下,从左往右依次访问结点。 ?

    55220

    【初探数据结构】二叉树的顺序结构——堆的实现详解(上下调整算法的时间复杂度分析)

    1.2 堆的重要性质 对于具有n个结点的完全二叉树,如果按照从上至下、从左至右的数组顺序对所有结点从0开始编号,对于序号为i的结点有: 若i > 0,i位置结点的双亲序号为:(i - 1)/2; 当i为...若2i + 1 孩子序号:2i + 1;如果2i + 1 >=n,则无左孩子 若2i + 2 孩子序号:2i + 2;如果2i + 2 >=n,则无右孩子 2....我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。...{ int child = 2 * parent + 1; while (child < n) { // 假设法,选出左右孩⼦中⼩的那个孩⼦ if (a[child] 最后⼀个元素进⾏交换 删除堆中最后⼀个元素 将堆顶元素向下调整到满⾜堆特性为⽌ void HeapPop(HP* php) { assert(php); assert(!

    28210

    从零开始学二叉树(中):堆与完全二叉树的奥秘

    堆是一种特殊的完全二叉树,满足: 大根堆:任意结点 ≥ 其孩子 → 根最大 小根堆:任意结点 ≤ 其孩子 → 根最小 ✅ 大根堆例子(数组表示): 数组:[90, 80, 70, 60, 50, 40...场景:删除堆顶(90),常规做法: 把最后一个元素(40)换到堆顶 → [40,80,70,60,50] 40 和左右孩子比:左=80,右=70 → 80 最大 40 < 80 → 交换 → [80,40,70,60,50...两种思路: 逐个插入(向上调整) 从空堆开始,一个个 HPPush O(n log n) 整体调整(向下调整) 从最后一个非叶子结点开始,倒着 AdjustDown O(n) ✅ 为什么向下调整建堆更快...(向下建堆): // 从最后一个非叶子结点开始调整 // 最后一个结点索引 = n-1 → 父 = (n-2)/2 = (n-1-1)/2 for (int i = (n - 1 - 1) / 2;...6️⃣ 堆的应用一:堆排序(Heap Sort) 思路 建大根堆(升序) 把堆顶(最大值)和最后一个元素交换 堆大小减 1,对新堆顶向下调整 重复 2~3,直到堆只剩一个元素 ✅ 原地排序:不需要额外数据结构

    11610

    可以管理时间的二叉堆

    今天我们来看一看什么是堆,以及堆的一般操作 然后我把优先级存入一个无序数组里,取出的时候遍历数组一边,找出最小值,插入的时候直接插到集合末尾 这样,父子关系就可以用下标来表示了,显然,在k下标处的节点的左孩子一定在...2*k小标处,右孩子在2*k+1处 当你插入一个元素的时候,很有可能破坏堆的有序性 每个父节点的值小于等于其左右孩子的值被称为堆的有序性 另一种情况是大于等于也称之为堆的有序性 克随手画了一个插入操作破坏堆有序性的图...谦子听完此话紧张的手心出汗,但还是硬着头皮想了想,突然灵光一现 我可以把堆顶的元素和堆的最后一个元素交换,然后逻辑上删除最后一个元素 谦子 这里我用一个heapSize变量记录堆中元素的个数,交换后heapSize...减一 谦子 随后谦子画出了交换后的图 这样我就通过交换堆顶元素与最后一个元素和heapSize减一把堆顶元素删除了 这个时候堆顶元素9来到了它的左孩子处,但是此时它大于现在的左右孩子 所以要继续下沉 此时下沉完毕...,如果该节点是左右孩子其中一个,则下沉,否则不下沉 谦子 慧子解释道,并画了一个图 这个思路不错,那你的那个找出最小节点下标的函数(minIndex())是如何实现的?

    68660

    手撕数据结构之二叉树

    void AdjustUp(HPDataType* arr, int child)//调整的是一个数组,第二个参数是要调整的数据的下标,将孩子往父亲的位置进行调整 { int parent =...(HPDataType*arr, int parent, int n) //第一个数据是我们要调整的数组,第二个参数是父节点,就是我们开始进行调整的位置的下标对应的元素,第三个是数组中有效的元素个数 {...,第二个参数是要调整的数据的下标,将孩子往父亲的位置进行调整 { int parent = (child - 1) / 2;//根据孩子求父亲的下标 //不需要等于,child只要走到根节点的位置...int n) //第一个数据是我们要调整的数组,第二个参数是父节点,就是我们开始进行调整的位置的下标对应的元素,第三个是数组中有效的元素个数 { //我们已知Parent,那么我们能够通过2i...我们再将队头取出,将队头的左右孩子放进去,如果孩子为空放个NULL进去 如果我们队列剩下的都是NULL的话,我们将队列中第一个NULL取出 那么我们取到的数据为空,取到为空的情况我们就跳出循环 那么最后就是这么个情况

    45610

    JS - 二叉树算法实现与遍历 (更新中...)

    前序遍历     顺序(中左右):先访问并打印当前节点的值,然后访问当前节点的左子树,最后访问当前节点的右子树     作用:复制一个已有的二叉树结构,性能是最高的。...直到找不到左孩子时这个才会停止,函数会一层一层的嵌套。那么,直到最后一层的叶子级别的左孩子,就不会继续调用这个函数了,也就是会遍历到树的最左下角的那个节点了。...,让他们依次当爸爸妈妈。...//如果该节点左边有分节点(左边有孩子)那么在左孩子的位置基础上,再次调用中序遍历函数,并把当前左孩子的值传给函数。直到找不到左孩子时这个才会停止,函数会一层一层的嵌套。...所以最后返回的都将是2。所以解决方法是这里return出去,让他停止继续递归。霍哈哈哈,所以我自己写的if判断的写法是有用的。

    3.8K80

    【初阶数据结构篇】算法中的秩序之美:顺序二叉树——堆的进阶之路(附源码)

    你的支持是我继续创作的动力! 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力!...序号: 2i+1 , 2i+1>=n 则⽆左孩⼦ 若 2i+2孩⼦序号: 2i+2 , 2i+2>=n 否则⽆右孩⼦ 堆的实现 堆的底层结构为数组 本篇建小堆!!!...HPTop(HP* php); // 判空 bool HPEmpty(HP* php); test.c 用来测试我们写的函数(函数的调用) 这一部分就是自己写的时候用的测试用例,随便什么都行 最好是写一个方法测试一次...arr[0], &php->arr[php->size - 1]); --php->size; AdjustDown(php->arr, 0, php->size); } 判断是否为空 将堆顶数据与最后一个数据交换...= child; child = parent * 2 + 1; } else { break; } } } 三个参数 需要调整的堆(数组) 父节点,因为出堆都是交换最后一个到栈顶

    35110

    一道魔性的贪心题目(随意吐槽)

    对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。...虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。所以你应该输出1。 (难道剩下一个饼干喂狗吗?????) 02 题解分析 好吧。...假如我们按照题目所说的策略来分析,尽可能的让孩纸满足,满足不了就一个饼干都不给他,忘掉那些懵逼的孩子。 其实策略就很简单了:我们只需要在满足孩子胃口的前提下,尽可能分配小的饼干给到他。...如果最大的饼干可以满足肚子最大的孩子,那就给他吃,同时比较下一个。 如果最大的饼干不能满足肚子最大的孩子,那就让他饿着,然后看看能不能满足第二个孩子。(有点黑暗系,放弃小朋友) 但是这里有个问题。...(放弃的是饼干) 那这两种其实都算是贪心: 一种是胃口太大轮到下一个孩子 一种是饼干太小轮到下一个饼干 因为要同时控制饼干和小孩,所以我们采用双指针。

    38710

    心理医生妈妈是怎样育儿的?

    对母亲的“依恋”实际上是小孩的一种本能。当小生命作为一个个体来到这个世界上,首先就是要活下去。...对婴儿来说,妈妈的怀抱是最温暖、最安全的, 当妈妈的一定要把这个感觉给孩子。孩子有了这种感觉,就有了一个稳定的心理基础,就不会一碰到点事儿就害怕,就焦虑,这样的孩子就比较容易适应环境的变化。...接受孩子,就是不管他是什么样的,我都接受你,而不是你能给我挣面子、让我高兴的时候我才接受你。当孩子知道妈妈能够接受一个完整的自己时,他才 自信。 如果光表扬,滥用表扬,也会出现问题。...如果父母老批评孩子,最后批评会变成孩子内心中的一个小人,即便父母不批评,这个小人也会自己批评自己,老对自己不满意,不接受自己,变得特别自卑。所以批评要特别讲究。 1、要对事不对人。...事实上孩子要不是犯错误,就不知道那个规矩,你告诉他这是规矩以后他就不会做这个事情了。另外还有一点,就是在批评孩子时发现他的优点。

    46320

    AVL树详解及旋转特性:

    这种树可以自己调节平衡性,保证每颗树的左右子树高度不会相差太多,来看看它是如何实现的: 在每个节点,加入一个变量:平衡因子: AVL树的每一颗子树都必须是AVL树 平衡因子的值==右子树的高度-左子树的高度...在双旋中,如果理解了单旋,旋转已经不成问题了,难的是最后平衡因子的调节,在单旋完后,我们都将parent subL或者subR的平衡因子都改为了0,但在双旋中不一样,上图是在b后面插入,最后的平衡因子为...最后调节平衡因子时就将parent的平衡因子设为1,其它为0; 如果为0(subLR作为新节点插入),最后所有平衡因子设为0。...同样最后的平衡因子调节也需要分情况,在旋转前,我们先记录subRL(图中60)的平衡因子: 如果为1(在subRL的右边插入),最后调节平衡因子时就将parent的平衡因子设为-1,其它为0; 如果为...-1(在subRL的左边插入),最后调节平衡因子时就将subR的平衡因子设为1,其它为0; 如果为0(subRL作为新节点插入),最后所有平衡因子设为0。

    35510
    领券