数据结构和算法之树形结构(1)

文章出处: 数据结构和算法之树形结构(1)  关注码农爱刷题,看更多技术文章!!

        树形结构是数据结构四种逻辑结构之一,也是被广泛使用的一种逻辑结构,它描述的是数据元素之间一对多的逻辑关系。树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合;它有一个起始节点,称之为根节点;从根节点往下逐层延伸,每个节点都可以有零个或多个子节点,有且只有一个父节点,根节点无父节点,形体像一棵倒挂的树,因而被称之为树形结构。 树形结构逻辑上有序的意思,就是从根节点往下延伸的顺序,因而和线性结构一样是有序结构。

       树形结构常用于表示具有层次关系的数据,例如文件系统、组织结构、目录结构等。它提供了一种便捷的方式来组织和访问数据。树形结构的应用非常广泛,例如在计算机科学中,树型结构被用于实现搜索算法(如二叉搜索树)、存储和检索数据(如B树、堆)、表达抽象语法树等。在现实生活中,树型结构也有很多应用,比如家谱、图书分类、产品组织关系等。

 一、基本概念

图片

 二、二叉树
      二叉树的定义

      二叉树是典型和常见的树形结构,也是最简单的树形结构。二叉树每个节点最多有两棵子树(二叉树中不存在度大于2的节点),并且二叉树的子树有左右之分,顺序不能颠倒。

     二叉树根据样式不同,还可以分为满二叉树和完全二叉树,例如下图:

图片

     若一棵树的层数为k,它总结点数是2^k-1,则这棵树就是满二叉树。上图编号2的树就是一棵满二叉树,该树4层节点数15 = 2^4-1;满二叉树的特点是叶子节点都在最底层,除了叶子节点,每个节点都有左右两个子节点。

      若一棵树的层数为k,它前k-1层的总结点数是2^(k-1)-1,第k层的结点按照从左往右的顺序排列,则这棵树就是完全二叉树。上图编号3的树就是一棵完全二叉树,该树4层前3层节点数7 = 2^(4-1)-1;完全二叉树的特点是:叶子节点都在最底下两层,最后一层的叶子节点都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大值2。看下图识别完全二叉树和非完全二叉树的区别。

图片

      此外, 满二叉树一定是一棵完全二叉树,但完全二叉树不一定是满二叉树。 

      二叉树的存储结构

      二叉树在实际落地时,可以采用顺序存储结构和链式存储结构,关于两者的区别可以参看前面的文章数据结构和算法之基本概念。如果是采用链式存储结构,一个节点分为三部分,其中数据域存储数据,另外两个指针域,一个指向左边的子节点,一个指向右边的子节点,这是一个典型的链表结构(关于链表结构说明可以参看文章数据结构和算法之线性结构)。通常,这是二叉树常用的存储结构。

      如果采用顺序存储结构,通常是采用数组来实现。那数组是如何存储二叉树节点数据的呢?  其存储规则是:从根节点开始,逐层往下、从左至右依次存储,看下图能更形象地理解其存储规则:

图片

       从上图可以看出:如果节点 X 存储在数组中下标为 i 的位置,下标为 2 * i 的位置存储的就是左子节点,下标为 2 * i + 1 的位置存储的就是右子节点;反过来,下标为 i/2 的位置存储就是它的父节点。通过这种方式,我们只要知道根节点存储的位置(一般情况下,为了方便计算子节点,根节点会存储在下标为1的位置),这样就可以通过下标计算,把整棵树都串起来。

       二叉树的遍历

        二叉树的遍历通常有两种搜索遍历方法:深度优先遍历广度优先遍历。深度优先遍历(Depth-First Search,简称DFS)即优先深入地探索一个节点的某一条路径,直到该路径都已被探索完,然后再回溯到该节点,探索该节点另一条路径,以此类推;广度优先遍历(Breadth-First Search,简称BFS)则是同时对所有路径逐层进行探索。

      深度优先遍历根据遍历的顺序不同,又可以细分为三种不同的遍历顺序:前序遍历、中序遍历、后序遍历。三种遍历顺序定义如下:

图片

      无论哪种遍历顺序,左节点都要优先右节点遍历, 三种遍历顺序实际遍历结果以下图为例:

图片

       前序遍历结果是:ABDHIEJCFG; 中序遍历结果是:HDIBJEAFCG;后序遍历结果是:HIDJEBFGCA。代码层面,通常我们可以通过递归实现前述深度优先遍历的三种遍历顺序,代码如下:

public class Solution { private static class Node { public int data;  // 节点值public Node left;  // 左节点  public Node right;  // 右节点public Node(int data, Node left, Node right) { this.data = data; this.left = left; this.right = right; } } public static void preDfs(Node treeNode) { if (treeNode == null) { return; } System.out.println(treeNode.data);  // 访问节点本身preDfs(treeNode.left);  // 遍历左节点preDfs(treeNode.right);  // 遍历右节点} public static void middleDfs(Node treeNode) { if (treeNode == null) { return; }        middleDfs(treeNode.left);  // 遍历左节点System.out.println(treeNode.data);  // 访问节点本身middleDfs(treeNode.right);  // 遍历右节点} public static void lastDfs(Node treeNode) { if (treeNode == null) { return; }        lastDfs(treeNode.left);  // 遍历左节点      lastDfs(treeNode.right);  // 遍历右节点System.out.println(treeNode.data);  // 访问节点本身} 
}

       如果是广度优先遍历,上面二叉树图遍历的结果则是:ABCDEFGHIJ;广度优先遍历符合队列先进先出的特点,实现时可以考虑用队列,如下面代码:


public static void bfs(Node root) {if (root == null) {return;}LinkedList<Node> queue = new LinkedList<Node>();Node current = null;// 根节点入队queue.offer(root);// 左侧数的深度int leftNum = 0;// 右侧数的深度int rightNum = 0;// 只要队列中有元素,就可以一直执行,非常巧妙地利用了队列的特性while (!queue.isEmpty()) {// 出队队头元素 先进先出current = queue.poll();System.out.print("-->" + current.data);// 左子树不为空,入队if (current.left != null) {queue.offer(current.left);leftNum++;}// 右子树不为空,入队if (current.right != null) {queue.offer(current.right);rightNum++;}}System.out.println(rightNum + "\t" + leftNum);
}

       上述代码中Node类的定义与之前代码里的Node类一致。代码逻辑分析:先是根节点入队,第一次循环,根节点出队(第一层),然后是第二层左右节点入队;第二次循环,左节点出队,左节点左右两孙节点入队;第三次循环,右节出队,右节点左右两孙节点入队,至此二层节点全部出队;第四次循环,左节点左孙节点出队,其左右子节点再入队,以此类推。

       深度广度优先遍历和广度优先遍历不仅仅用于二叉树的遍历,事实上,两者是两种基本且重要的图与树的遍历算法,它们的应用场景和优缺点如下图表:

图片

       本章主要介绍了树形结构的基本概念和特点,以及二叉树的定义、存储结构和遍历算法,关于树形结构的深入知识将在后续文章继续介绍,烦请关注!!    

码农爱刷题

为计算机编程爱好者和从业人士提供技术总结和分享 !为前行者蓄力,为后来者探路!

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

SOMEIP_ETS_119: SD_Indicate_wrong_l4proto_param

测试目的&#xff1a; 验证DUT能够拒绝一个引用了带有错误l4proto参数&#xff08;既不是UDP也不是TCP&#xff09;的IPv4端点选项的SubscribeEventgroup消息&#xff0c;并以SubscribeEventgroupNAck作为响应。 描述 本测试用例旨在确保DUT遵循SOME/IP协议&#xff0c;当接…

基于单片机的智能电话控制系统设计

摘要&#xff1a; 为了能够使用电话实现电器设备的控制&#xff0c;文中通过单片机及双音多频解码集成电路&#xff0c;使用用 户通过电话输入相应的指令就能够实现远程设备的智能化控制。文章主要对系统的构成、软件及 硬件设计进行了简单的介绍&#xff0c;并且对其中的电路…

出现conda不是内部或外部命令,也不是可运行的程序或批处理文件。的解决办法

发现是我的环境变量不对&#xff0c;需要改成conda.exe所在的目录下 如果不知道自己conda.exe在哪的 可以下载个everything这个软件 找东西很快 找到后 点击环境变量-系统变量-Path-新建-&#xff08;你的conda.exe所在目录&#xff1a;绝对路径&#xff09; 完成上述操作…

Day4:杨辉三角

题目&#xff1a;给定一个非负整数numRows,生成杨辉三角的前numRows行。在杨辉三角中&#xff0c;每个数就是左上方和右上方数的和。 import java.util.ArrayList; import java.util.List;public class Test {public static List<List<Integer>> generate(int numR…

【学术会议征稿】2024年先进控制系统与自动化技术国际学术会议(ACSAT 2024)

2024年先进控制系统与自动化技术国际学术会议&#xff08;ACSAT 2024&#xff09; 2024 International Conference on Advanced Control Systems and Automation Technologies 2024年先进控制系统与自动化技术国际学术会议&#xff08;ACSAT 2024&#xff09;将于2024年11月15…

solidwork装配体取消零件固定

前面有固定导致零件移动不了 右键&#xff0c;找到浮动

Three.js 3D人物漫游项目(上)

本文目录 前言1、项目构建1.1 安装依赖1.2 初始化1.3 项目结构1.4 初始化的项目运行 2、加载模型2.1 threejs三要素2.1.1 代码解读 2.2 加载模型2.2.1 代码解读 2.3 效果 前言 在数字技术的浪潮中&#xff0c;三维图形渲染技术以其独特的魅力&#xff0c;正逐步渗透到我们生活的…

react hooks--useMemo

概述 相当于计算属性!!! useMemo实际的目的也是为了进行性能的优化。 ◼ 如何进行性能的优化呢&#xff1f;  useMemo返回的也是一个 memoized&#xff08;记忆的&#xff09; 值&#xff1b;  在依赖不变的情况下&#xff0c;多次定义的时候&#xff0c;返回的值是相同…

后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0920)

十三、文章分类页面 - [element-plus 表格] Git仓库&#xff1a;https://gitee.com/msyycn/vue3-hei-ma.git 基本架子 - PageContainer 功能需求说明&#xff1a; 基本架子-PageContainer封装文章分类渲染 & loading处理文章分类添加编辑[element-plus弹层]文章分类删除…

k8s中的微服务

目录 一、什么是微服务 二、微服务的类型 三、IPVS模式 1、ipvs模式配置方式 &#xff08;1&#xff09;在所有节点中安装ipvsadm &#xff08;2&#xff09;修改master节点的代理配置 &#xff08;3&#xff09;重启pod 四、微服务类型详解 1、clusterip 示例&#…

Flink提交任务

第3章 Flink部署 3.1 集群角色 3.2 Flink集群搭建 3.2.1 集群启动 0&#xff09;集群规划 表3-1 集群角色分配 具体安装部署步骤如下&#xff1a; 1&#xff09;下载并解压安装包 &#xff08;1&#xff09;下载安装包flink-1.17.0-bin-scala_2.12.tgz&#xff0c;将该jar包…

有什么兼容macOS 15 Sequoia系统的加密软件?

前言&#xff1a;近日&#xff0c;苹果更新了 macOS 15 Sequoia正式版&#xff0c;已经有用户在电脑上安装使用了。在这个信息化时代&#xff0c;系统一直在更新&#xff0c;运用一些工具时需要考虑兼容性。 刚有个客户来问迅软&#xff1a;你们迅软DSE客户端支持新发布的macO…

Linux 磁盘清理重新格式化挂载脚本及问题解决

Linux 磁盘清理重新格式化挂载脚本&#xff1a;diskformat.sh #!/bin/bash for i in {1…8} do umount /data0$i done PIDARRAY() for i in a b c d e f g h do parted -s /dev/sd i m k l a b e l g p t p a r t e d − s / d e v / s d i mklabel gpt parted -s /dev/sd im…

【高阶数据结构】二叉搜索树的插入、删除和查找(精美图解+完整代码)

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《高阶数据结构》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多《高阶数据结构》点击专栏链接查看&a…

【计算机网络篇】计算机网络概述

本文主要介绍计算机网络第一章节的内容&#xff0c;文中的内容是我认为的重点内容&#xff0c;并非所有。参考的教材是谢希仁老师编著的《计算机网络》第8版。跟学视频课为河南科技大学郑瑞娟老师所讲计网。 文章目录 &#x1f3af;一.计算机网络的组成 ✨主要内容 1.边缘部…

seL4 Capabilities(翻自官网)(一)

官网教程链接: Capability 初始化Capabilities tutorials // 先使用repo拉取一下tutorials&#xff0c;然后执行repo sync&#xff0c;所有的教程都在里面&#xff0c;学习某个的时候只需要改变的是 --tut 后面的参数 ./init --tut capabilities # building the tutorial exe…

国内可以使用的ChatGPT服务【9月持续更新】

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…

演示:基于WPF的DrawingVisual开发的Chart图表和表格绘制

一、目的&#xff1a;基于WPF的DrawingVisual开发的Chart图表和表格绘制 二、预览 钻井井轨迹表格数据演示示例&#xff08;应用Table布局&#xff0c;模拟井轨迹深度的绘制&#xff09; 饼图表格数据演示示例&#xff08;应用Table布局&#xff0c;模拟多个饼状图组合显示&am…

git使用“保姆级”教程2——初始化及工作机制解释

1、设置用户签名 解释&#xff1a; 签名的作用就是用来&#xff1a;标识用户&#xff0c;以区分不同的开发人员简单来说&#xff1a;用来标识"你是谁"&#xff0c;在提交代码时&#xff0c;会显示提交代码的是谁&#xff0c;把设置的信息一起提交上去 设置&#xff…

weblogic CVE-2019-2725 靶场攻略

漏洞描述 wls9-async等组件为WebLogic Server提供异步通讯服务&#xff0c;默认应⽤于WebLogic部分版本。由于该 WAR包在反序列化处理输⼊信息时存在缺陷&#xff0c;攻击者通过发送精⼼构造的恶意 HTTP 请求&#xff0c;即可获得⽬标服务器的权限&#xff0c;在未授权的情况…