当前位置: 首页 > news >正文

数据结构【堆(⼆叉树顺序结构)和⼆叉树的链式结构】

Hello大家好! 很高兴与大家见面! 给生活添点快乐,开始今天的编程之路。

我的博客:<但愿.

文章专栏:算法与数据结构

我的专栏:C语言、题目精讲、算法与数据结构、C++

若有问题评论区下讨论,我会及时回答

欢迎大家点赞、关注、收藏分享

目录

       1 堆(顺序结构⼆叉树)

            1.1定义

            1.2分类

            1.3  堆的实现

            1.4  堆的应⽤

                     1.4.1 堆排序

                              1.4.1.1堆排序的实现

                              1.4.1.2向上调整法与向下调整法哪种更好?

                                         向上调整法思路

                                         向上调整法时间复杂度

                                         向下调整法思路

                                         向下调整法时间复杂度 

                              1.4.2 TOP-K问题【大量数据中排出少量最值数据,例如世界排名】

        2 链式结构⼆叉树

            2.1链式结构⼆叉树的概念

            2.2链式结构⼆叉树相关方法的实现

                             2.2.1前中后序遍历 

                             2.2.2⼆叉树结点个数

                            2.2.3⼆叉树叶⼦结点个数

                            2.2.4 ⼆叉树第k层结点个数

                            2.2.5⼆叉树的高度/深度

                            2.2.6 ⼆叉树查找值为x的结点

                            2.2.7⼆叉树销毁

                            2.2.8 层序遍历

                            2.2.9判断是否为完全⼆叉树

1 堆(顺序结构⼆叉树)

 1.1定义

         堆是⼀种特殊的⼆叉树,只不过其底层结构是顺序结构的数组来存储数据,所以堆不仅具有⼆叉树的特性的同时,还具备其他的特性。

 1.2分类

        大堆(大根堆):根节点最大的堆
        小堆(小根堆):根节点最小的堆

1.3  堆的实现

堆底层结构为数组,因此定义堆的结构为:
//堆的结构
typedef int HPDataType;
typedef struct Heap 
{HPDataType* arr;int size;      //有效数据个数int capacity;  //空间大小
}HP;

堆相关方法的实现:

1.4  堆的应⽤

 1.4.1 堆排序
          1.4.1.1堆排序的实现

1.4.1.2向上调整法与向下调整法哪种更好?

 向上调整法思路:

将堆顶元素与堆中最后⼀个元素进⾏交换
删除堆中最后⼀个元素
将堆顶元素向下调整到满⾜堆特性为⽌

 向上调整法时间复杂度(因为完全二叉树和满二叉树在计算时间复杂度时相差不大所以我们将其当成满二叉树来计算)

分析:
第1层, 2 0 个结点,需要向上移动0层
第2层, 2 1 个结点,需要向上移动1层
第3层, 2 2 个结点,需要向上移动2层
第4层, 2 3 个结点,需要向上移动3层
......
第h层, 2 h−1 个结点,需要向上移动h-1层
则需要移动结点总的移动步数为:每层结点个数 * 向上调整次数(第⼀层调整次数为0)
       所以向上调整时间复杂度是:T (h) = 2 1 ∗ 1 + 2 2 ∗ 2 + 2 3 ∗ 3 + .. + 2 h−2 ∗ (h − 2) + 2 h−1 ∗ (h − 1)
根据⼆叉树的性质: n = 2 h − 1 h = log2 (n + 1)
F (n) = (n + 1)(log2 (n + 1) − 2) + 2
由此可得:向上调整算法建堆时间复杂度为: O(n ∗ log2 n)

 向下调整法思路:

将堆顶元素与堆中最后⼀个元素进⾏交换
删除堆中最后⼀个元素
将堆顶元素向下调整到满⾜堆特性为⽌

向下调整法时间复杂度

分析:
第1层, 2 0 个结点,需要向下移动h-1层
第2层, 2 1 个结点,需要向下移动h-2层
第3层, 2 2 个结点,需要向下移动h-3层
第4层, 2 3 个结点,需要向下移动h-4层
......
第h-1层, 2 h−2 个结点,需要向下移动1层
则需要移动结点总的移动步数为:每层结点个数 * 向下调整次数
      所以 向下调整法T (h) = 2 0 ∗ (h − 1) + 2 1 ∗ (h − 2) + 2 2 ∗ (h − 3) + 2 3 ∗ (h − 4) + .. + 2 h−3 ∗ 2 + 2 h−2 ∗ 1
根据⼆叉树的性质: n = 2 h − 1 h = log2 (n + 1)
T (n) = n log2 (n + 1) ≈ n
由此可得:向下调整算法建堆时间复杂度为: n
所以向下调整法相对更好

 1.4.2 TOP-K问题【大量数据中排出少量最值数据,例如世界排名】

下面我们通过一道题目来讲解

TOP-K问题:即求数据结合中前K个最⼤的元素或者最⼩的元素,⼀般情况下数据量都⽐较⼤。
⽐如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。
对于Top-K问题,能想到的最简单直接的⽅式就是排序,但是:如果数据量⾮常⼤,排序就不太可取了(可能数据都不能⼀下⼦全部加载到内存中)。最佳的⽅式就是⽤堆来解决。
思路:
这里一个重要的问题,怎么建堆(建空间多大的堆)是有多少个数据就建多少个数据的总空间大小的堆吗?那如果数据很多这也太浪费空间和时间了。有如果题目规定了给顶的空间很小了这时候应该怎么办呢?其实我们只要通过要取多少个最值就建相应大小空间的堆,在⽤剩余元素依次与堆顶元素来⽐较,不满⾜则替换堆顶元素(例如有N个数据,要得到前K个最⼤的元素或者最⼩的元素,我们只须⽤数据集合中前K个元素来建堆,⽤剩余的N-K个元素依次与堆顶元素来⽐较,不满⾜则替换堆顶元素)
总体思路
1)⽤数据集合中前K个元素来建堆
前k个最⼤的元素,则建⼩堆
前k个最⼩的元素,则建⼤堆
2)⽤剩余的N-K个元素依次与堆顶元素来⽐较,不满⾜则替换堆顶元素将剩余N-K个元素依次与堆顶元素⽐完之后,堆中剩余的K个元素就是所求的前K个最⼩或者最⼤的元素

代码实现:

链式结构⼆叉树

2.1链式结构⼆叉树的概念

    ⽤链表来表⽰⼀棵⼆叉树,即⽤来指⽰元素的逻辑关系。 通常的⽅法是链表中每个结点由三个域组成数据域和左右指针域,左右指针分别⽤来给出该结点左孩⼦和右孩⼦所在的链结点的存储地址

2.2链式结构⼆叉树相关方法的实现

   2.2.1前中后序遍历
 
  2.2.2⼆叉树结点个数
2.2.3⼆叉树叶⼦结点个数

2.2.4 ⼆叉树第k层结点个数

2.2.5⼆叉树的高度/深度

2.2.6 ⼆叉树查找值为x的结点

2.2.7⼆叉树销毁

2.2.8 层序遍历

2.2.9判断是否为完全⼆叉树

本篇文章就到此结束,欢迎大家订阅我的专栏,欢迎大家指正,希望有所能帮到读者更好了算法与数据结构相关知识 ,觉得有帮助的还请三联支持一下~后续会不断更新算法与数据结构相关知识,我们下期再见。

http://www.dtcms.com/a/392153.html

相关文章:

  • 我爱学算法之—— 位运算(下)
  • LeetCode第364题_加权嵌套序列和II
  • 云计算和云手机之间的关系
  • 胡服骑射对中国传统文化的影响
  • leetcode-hot-100 (多维动态规划)
  • Chromium 138 编译指南 Ubuntu 篇:depot_tools安装与配置(三)
  • 在Ubuntu 16.04上安装openjdk-6/7/8-jdk的步骤
  • 小杰机器学习高级(four)——基于框架的逻辑回归
  • 基于AI分类得视频孪生鹰眼图像三维逆变换矫正算法
  • [Tongyi] 智能代理搜索范式 | 决策->行动->观察(循环迭代)
  • FLink:窗口分配器(Window Assigners)指定窗口的类型
  • GO实战项目:流量统计系统完整实现(Go+XORM+MySQL + 前端)
  • 零基础-动手学深度学习-13.10. 转置卷积
  • 【Math】初三第一、二单元测试卷(测试稿)
  • 2.Spring AI的聊天模型
  • 【连载6】 C# MVC 日志管理最佳实践:归档清理与多目标输出配置
  • autodl平台jupyterLab的使用
  • React学习教程,从入门到精通,React 开发环境与工具详解 —— 语法知识点、使用方法与案例代码(25)
  • 【C++】容器进阶:deque的“双端优势” vs list的“链式灵活” vs vector的“连续高效”
  • llm的ReAct
  • C++ 参数传递方式详解
  • 前端实战开发(一):从参数优化到布局通信的全流程解决方案
  • iOS 层级的生命周期按三部分(App / UIViewController / UIView)
  • 第一章 自然语言处理领域应用
  • GitHub又打不开了?
  • OpenAI回归机器人:想把大模型推向物理世界
  • QML学习笔记(五)QML新手入门其三:通过Row和Colunm进行简单布局
  • 按键检测函数
  • CTFshow系列——PHP特性Web109-112
  • 字符函数与字符串函数