数据结构篇——二叉树的存储与遍历

     一、引入   


        书接上文,文于此续。上文我们学到了树的存储结构,那么今天,我们来学习下几种特殊的二叉树以及关于它的各种遍历,让我们一起加油吧。

二、特殊的二叉树


        二叉树的特殊形式这里介绍3种,其中需要着重记忆的有满二叉树完全二叉树。其余1种大家了解认识即可。

1、斜树:

        就跟他的名字一样,所有结点只有左子树的叫做左斜树,只有右子树的叫做右斜树。具体图示如下:

2、满二叉树:

        满二叉树其实就是每个结点(除开叶子结点)的左右子树都齐全的树即深度为k且含有2^{k-1}个结点的二叉树,如图所示:

        满二叉树的特点主要是:每一层上的结点树都是最大结点树,即每一层i的结点树都有最大值2^{i-1}。 可以对满二叉树按层序编号:约定编号从根结点(根结点编号为1)起,自上而下,自左向右。由此就能引出完全二叉树的定义。

3、完全二叉树:

        深度为k、有n 个结点的二叉树,当且仅当其每个结点都与深度为k的满二叉树中编号为1~n的结点一一对应时,称为完全二叉树,如下图所示:

        完全二叉树的特点是:

  1. 叶子结点只可能在层次最大的两层上出现。
  2. 对于任意结点,若其右分支下的子孙的最大层次为l,则其左分支下子孙最大层次一定是l或l+1层。

这里提出两个关于完全二叉树的性质:

  1. 具有n个结点的完全二叉树的深度为不大于\log_{2}n+1的最大整数。
  2. 如果对一颗有n个结点的完全二叉树(其深度为不大于\log_{2}n+1的最大整数)的结点按层序编号,则对任意结点i有:
         (1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲PARENT (i)是结点[i/2]。
         (2)如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子LCHILD(t)是结点2i。
         (3)如果2i+1>n,则结点i无右孩子;否则其右孩子RCHILD(i)是结点2i+1。

三、二叉树的存储结构 


        二叉树的存储结构和线性表类似,主要采用顺序和链式两种存储结构。

 1、顺序存储结构:

        顺序结构通常是采用一组连续的地址来存储数据,术语为了能够顺利的存储二叉树中的数据,就必须按照一定的规律来顺序来排放。

        对于完全二叉树来说,只要从根起按层序存储即可,依次从上至下,从左往右来存储树中的结点并编号。这样,编号为i的结点元素就会存储在一维数组中下标为i-1的分量当中。

        而对于一般二叉树来说,也按照完全二叉树那般排列,只是在一般二叉树中没有的部分就用“0”来表示,具体的图示如下:        从图中我们不难发现,这种顺序存储的结构只适用于完全二叉树,对于一般的二叉树来说就会造成大量的空间浪费。所以对于一般的二叉树来说更适合链式存储法。

2、链式存储法:

        同线性表的链式存储一般,想要实现一个链表就得确定其每一个结点的结构。对于二叉树来说,如下图所示的(a)它的结构主要分为数据域(data)、两个指向左右子树的指针域和一个指向双亲的指针域。通过这样分析我们就能确定其结构。那让我们仔细想想,指向双亲的指针域好像不是必要的。所以,我们就能发现,带有双亲指针域的存储结构多为三叉链表、反之则为二叉链表分别如下图中的(c)、(b)所示:

        关于二叉树的链式存储结构,可以参考下图理解:

         结合树的存储结构我们就能用代码表示出如下结构:

typedef struct BiTNode{TElemType data;    //结点数据域struct BiTNode *lchild,*rchild;    //左右子树指针域
}BiTNode,*BiTree;

四、二叉树的遍历 


        遍历二叉树是指从根结点开始,按照某条搜索路径了解寻访树中的每一个结点,使得树中的每一个结点都被访问一次且只被访问一次。其中主要的方法有先序遍历、中序遍历、后序遍历及其各种演化。

1、先序遍历:

        顾名思义,用自然语言表达则是:先访问根节点A,再按此规则递归遍历左子树(B - D - G - H),最后递归遍历右子树(C - E - I - F ),序列为A B D G H C E I F 。具体实现如下图所示:

具体的算法步骤如下:

  1. 访问根结点;
  2. 先序遍历左子树;
  3. 先序遍历右子树。

代码描述:

void PreOrder(BiTree T){if(T != NULL){visit(T);	//访问根节点PreOrder(T->lchild);	//递归遍历左子树PreOrder(T->rchild);	//递归遍历右子树}
}

2、中序遍历:

        自然语言描述:先左子树(G - D - H ),再根节点(A ),后右子树(I - E - C - F ),序列为G D H B A I E C F 。具体实现如下图所示:

算法步骤:

  1. 中序遍历左子树;
  2. 访问根结点;
  3. 中序遍历右子树。 

代码描述:

void InOrder(BiTree T){if(T != NULL){InOrder(T->lchild);	//递归遍历左子树visit(T);	//访问根结点InOrder(T->rchild);	//递归遍历右子树}
}

 3、后序遍历:

        自然语言描述:先左子树(G - H - D ),再右子树(I - F - E ),最后根节点A,序列为G H D B I F E C A 。具体实现如下图所示:

算法步骤:

  1. 后序遍历左子树;
  2. 后序遍历右子树;
  3. 访问根结点。 

代码描述:

void PostOrder(BiTree T){if(T != NULL){PostOrder(T->lchild);	//递归遍历左子树PostOrder(T->rchild);	//递归遍历右子树visit(T);	//访问根结点}
}

 以上就是二叉树最基础的三种遍历方法了。先偷偷懒,咱下期再见。

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/37207.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vulnhub-wordpress通关攻略

姿势一、后台修改模板拿WebShell 第一步:进⼊Vulhub靶场并执⾏以下命令开启靶场;在浏览器中访问并安装好.... 第二步:找到外观--编辑--404.php,将原内容删除并修改为一句话木马,点击更新--File edited successfully. &…

「清华大学、北京大学」DeepSeek 课件PPT专栏

你要的 这里都打包好啦,快快收藏起来! 名称 链接 团队简介 类型 DeepSeek——从入门到精通 1️⃣ DeepSeek从入门到精通「清华团队」 清华大学新闻与传播学院 新媒体研究中心 元宇宙文化实验室 PPT课件 DeepSeek如何赋能职场应用? ——从提示语…

【docker】--- 详解 WSL2 中的 Ubuntu 和 Docker Desktop 的区别和关系!

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【WSL 】--- Windows11 迁移 WSL 超详细指南 —— 给室友换一个宿舍! 开发环境一、引…

【图像处理基石】什么是HDR图片?

1. 什么是HDR图片? HDR(高动态范围图像,High Dynamic Range)是一种通过技术手段扩展照片明暗细节的成像方式。以下是关于HDR的详细说明: 核心原理 动态范围:指图像中最亮和最暗区域之间的亮度差。人眼能…

HarmonyOS Next中的弹出框使用

HarmonyOS Next弹出框概述及分类 弹出框是一种模态窗口,通常用于在保持当前上下文环境的同时,临时展示用户需关注的信息或待处理的操作。用户需在模态弹出框内完成相关交互任务之后,才能退出模态模式。弹出框可以不与任何组件绑定&#xff0…

Java多线程与高并发专题——为何每次用完 ThreadLocal 都要调用 remove()?

什么是内存泄漏 首先,我们要知道这个事情和内存泄漏有关,所以就让我们先来看一下什么是内存泄漏。 内存泄漏指的是,当某一个对象不再有用的时候,占用的内存却不能被回收,这就叫作内存泄漏。 因为通常情况下&#xf…

视频推拉流EasyDSS点播平台云端录像播放异常的问题排查与解决

视频推拉流EasyDSS视频直播点播平台可提供一站式的视频转码、点播、直播、视频推拉流、播放H.265视频等服务,搭配RTMP高清摄像头使用,可将无人机设备的实时流推送到平台上,实现无人机视频推流直播、巡检等应用。 有用户反馈,项目现…

《笔记》Android 获取第三方应用及查看应用信息、apk大小、缓存、存储,以及第三方清除缓存

获取应用相关信息&#xff1a; PS:manifest标签中设置以下属性表示系统应用 android:process"system" android:sharedUserId"android.uid.system" //获取所有应用&#xff08;非系统apk&#xff0c;有些应用获取不到&#xff09; List<ApplicationInf…

【保姆级教程】Windows系统+ollama+Docker+Anythingllm部署deepseek本地知识库问答大模型,可局域网多用户访问

目录 1.Ollama 本地化部署 DeepSeek R1 1.1下载Ollama 1.2安装Ollama 1.3安装DeepSeek R1大模型 2.系统环境配置 2.1开启系统功能 2.2安装wsl 3.安装 Docker Desktop并拉取Anythingllm镜像 3.1从 Docker 官网 下载并安装。 3.2拉取镜像 3.3运行 Docker 命令 4.anyth…

Sensodrive机器人力控关节模组SensoJoint在海洋垃圾清理机器人中的拓展应用

海洋污染已成为全球性的环境挑战&#xff0c;其中海底垃圾的清理尤为困难。据研究&#xff0c;海洋中约有2600万至6600万吨垃圾&#xff0c;超过90%沉积在海底。传统上&#xff0c;潜水员收集海底垃圾不仅成本高昂&#xff0c;而且充满风险。为解决这一问题&#xff0c;欧盟资助…

【redis】AOF 的基本工作机制,顺序写入,文件同步,重写机制

RDB 最大的问题&#xff0c;就是不能实时的持久化保存数据&#xff0c;在两次生成快照之间&#xff0c;实时的数据可能会随着重启而丢失 基本工作机制 AOF&#xff1a;append only file&#xff0c;类似于 MySQL 的 binlog&#xff0c;会把每个用户的每个操作&#xff0c;都记…

【C++】动态规划从入门到精通

一、动态规划基础概念详解 什么是动态规划 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;是一种通过将复杂问题分解为重叠子问题&#xff0c;并存储子问题解以避免重复计算的优化算法。它适用于具有以下两个关键性质的问题&#xff1a; 最优子结构&…

数据可视化(matplotlib)-------辅助图标的设置

目录 一、认识图表常用的辅助元素 坐标轴 二、设置坐标轴的标签、刻度范围和刻度标签 &#xff08;一&#xff09;、设置坐标轴的标签 1、xlabel()------设置x轴标签 2、ylabel()------设置y轴标签 &#xff08;二) 、设置刻度范围和刻度标签 1、xlim()和ylim()函数分别可…

CSS 用于图片的样式属性

CSS 设置图像样式 CSS中用于图片的样式属性主要包括以下几个方面&#xff1a; ‌边框和背景‌&#xff1a; ‌border‌&#xff1a;可以设置图片的边框样式、宽度和颜色。例如&#xff0c;img { border: 1px solid #ddd; } 会给图片添加1像素的实线边框&#xff0c;颜色为灰色…

Redis解决缓存击穿问题——两种方法

目录 引言 解决办法 互斥锁&#xff08;强一致&#xff0c;性能差&#xff09; 逻辑过期&#xff08;高可用&#xff0c;性能优&#xff09; 设计逻辑过期时间 引言 缓存击穿&#xff1a;给某一个key设置了过期时间&#xff0c;当key过期的时候&#xff0c;恰好这个时间点对…

Object 转 JSONObject 并排除null和““字符串

public static JSONObject objToJSONObject(Object obj) throws Exception{//创建一个 HashMap 对象 map&#xff0c;用于存储对象的属性名和属性值。//key 是属性名&#xff08;String 类型&#xff09;&#xff0c;value 是属性值&#xff08;Object 类型&#xff09;Map<…

python实现接口自动化

代码实现自动化相关理论 代码编写脚本和工具实现脚本区别是啥? 代码&#xff1a; 优点&#xff1a;代码灵活方便缺点&#xff1a;学习成本高 工具&#xff1a; 优点&#xff1a;易上手缺点&#xff1a;灵活度低&#xff0c;有局限性。 总结&#xff1a; 功能脚本&#xff1a;工…

C++特性——RAII、智能指针

RAII 就像new一个需要delete&#xff0c;fopen之后需要fclose&#xff0c;但这样会有隐形问题&#xff08;忘记释放&#xff09;。RAII即用对象把这个过程给包起来&#xff0c;对象构造的时候&#xff0c;new或者fopen&#xff0c;析构的时候delete. 为什么需要智能指针 对于…

算法系列——有监督学习——4.支持向量机

一、概述 支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一种应用范围非常广泛的算法&#xff0c;既可以用于分类&#xff0c;也可以用于回归。 本文将介绍如何将线性支持向量机应用于二元分类问题&#xff0c;以间隔&#xff08;margin&#x…

网络安全之前端学习(HTML篇)

前言&#xff1a;网络安全中有一个漏洞叫xss漏洞&#xff0c;就是利用网页引发弹窗&#xff0c;这就要求我们看得懂源码&#xff0c;所以我会持续更新前端学习&#xff0c;可以不精通&#xff0c;但是一定要会&#xff0c;主要掌握HTML&#xff0c;css&#xff0c;js这三项技术…