数据结构--》解锁数据结构中树与二叉树的奥秘(一)

        数据结构中的树与二叉树,是在建立非线性数据结构方面极为重要的两个概念。它们不仅能够模拟出生活中各种实际问题的复杂关系,还常被用于实现搜索、排序、查找等算法,甚至成为一些大型软件和系统中的基础设施。

        无论你是初学者还是进阶者,本文将为你提供简单易懂、实用可行的知识点,帮助你更好地掌握树和二叉树在数据结构和算法中的重要性,进而提升算法解题的能力。接下来让我们开启数据结构与算法的奇妙之旅吧。

目录

树和森林的概念

树的常考性质

二叉树的定义及其性质

二叉树的表示

二叉树遍历


树和森林的概念

树的定义:树是一种非线性的数据结构,它由节点(node)和边(edge)组成。树的基本概念是以层次结构来组织和表示数据。

在树中,有一个特殊的节点被称为根节点(root),它是树的顶层节点,所有其他节点都直接或间接地与根节点相连。除了根节点外,每个节点可以有零个或多个子节点(child),子节点又可以有自己的子节点,形成了树的分支结构。没有子节点的节点被称为叶节点(leaf)或叶子节点,它们位于树的最底层。节点之间的连接称为边,边描述了节点之间的关系。每个节点可以有零条到多条边连接到其子节点。任意两个节点之间都存在唯一的路径,通过路径可以从一个节点到达另一个节点。

树的结构具有以下特点

  1. 一个树可以由零个或多个节点组成。
  2. 有且只有一个根节点,它是树的起点。
  3. 每个节点可以有零个或多个子节点。
  4. 节点之间通过边相连,形成层次结构。
  5. 每个节点除了根节点外,都有且只有一个父节点。

树的基本术语

结点之间的关系描述

        根节点(Root Node):树的顶层节点称为根节点。根节点是树的起点,它没有父节点,其他所有节点都直接或间接地与根节点相连。

        祖先节点(Ancestor Node):对于一个节点,它的所有上级节点(包括父节点、父节点的父节点等等)都被称为该节点的祖先节点。

        子孙节点(Descendant Node):对于一个节点,它的所有下级节点(包括子节点、子节点的子节点等等)都被称为该节点的子孙节点。

        父节点(Parent Node):一个节点的直接上一级节点称为其父节点。每个节点都可以有零个或多个子节点,但只能有一个父节点(除了根节点)。

        子节点(Child Node):一个节点直接连接的下一级节点称为其子节点。一个节点可以有零个或多个子节点。

        兄弟节点(Sibling Node):具有相同父节点的节点称为兄弟节点。兄弟节点在同一层级上。

        叶节点(Leaf Node):也称为叶子节点,是没有子节点的节点,位于树的最底层。

        层级(Level):根节点在第一层,其直接子节点在第二层,以此类推。一个节点所在的层级数即为该节点的层级。

结点、树的属性描述

        节点值(Node Value):每个节点都可以携带一个值或数据,表示该节点所代表的实际含义或信息。

        节点深度(Node Depth):节点深度指的是该节点到根节点的路径长度,即从根节点到该节点所经过的边的数量。根节点的深度为0。

        节点高度(Node Height):节点高度指的是该节点到其最远叶节点的路径长度,即从该节点到达最远叶节点所经过的边的数量。叶节点的高度为0。

        子树(Subtree):对于一个树中的节点,可以以该节点为根构成的子树称为该节点的子树。

        树的大小(Tree Size):指的是树中包含的所有节点的总数。

        树的高度(Tree Height):指的是树中任意节点的高度的最大值。也可以理解为从根节点到最远叶节点的路径长度的最大值。

有序树、无序树

        有序树(Ordered Tree):有序树是指树中的子节点之间存在明确的顺序关系。在有序树中,每个子节点都有一个明确定义的位置,在遍历和表示树的时候需要按照顺序来考虑。例如,家谱树中的兄弟姐妹一般按照他们出生的先后顺序排列。

        无序树(Unordered Tree):无序树是指树中的子节点之间没有明确的顺序关系。在无序树中,所有子节点都是平等的,没有先后之分。例如,文件系统中的目录结构就是一种无序树,其中的各个子目录之间没有特定的顺序。

        有序树和无序树的区别在于子节点的排列方式。在有序树中,子节点的顺序很重要,会影响到树的结构和含义;而在无序树中,子节点的顺序并不重要,只需要知道它们是该节点的子节点即可。

森林

森林(Forest)是指由多棵树(Tree)组成的集合。简单来说,森林可以看作是多个独立的树的集合。

森林的特点在于其中的树之间是相互独立的,彼此之间没有直接的连接或关系。每棵树都可以独立地进行遍历和操作。

需要注意的是,森林和树的层次结构是不同的概念。树是一种层次结构,它具有唯一的根节点和从根节点到其他节点的确定路径;而森林则是多个独立的树的集合,在森林中任意两棵树之间没有直接的联系。

树的抽象数据类型

树的抽象数据类型定义了对树进行操作的基本操作集合,包括以下常见操作:

1)创建树:创建一个空的树数据结构。

2)插入节点:在树中插入一个新节点,并建立节点之间的关系。

3)删除节点:从树中删除指定的节点,并调整节点之间的关系。

4)遍历树:按照特定的顺序访问树中的节点,例如先序遍历、中序遍历、后序遍历等。

5)查找节点:在树中查找指定的节点。

6)获取树的属性:获取树的高度、节点个数、根节点等属性信息。

树的抽象数据类型并不关注具体的实现方式,而是定义了可以对树进行的操作以及这些操作的预期行为。

回顾重点,其主要内容整理成如下内容:  

树的常考性质

常见考点1:结点数 = 总度数 + 1

常见考点2:度为m的树、m叉树的区别

常见考点3:度为m的树第i层至多有  m^{i-1} 个结点 (i \geq 1),同理m叉树第i层至多有 m^{i-1} 个结点 (i \geq 1):

常见考点4:高度为h的m叉树至多有 \frac{m^{h}-1}{m-1} 个结点。

常见考点5:高度为h的m叉树至少有h个结点。高度为h度为m的树至少有h+m-1个结点。

常见考点6:具有n个结点的m叉树的最小高度为 log_m(n(m-1)+1)

高度最小的情况——所有结点都有m个孩子:

回顾重点,其主要内容整理成如下内容:   

二叉树的定义及其性质

二叉树定义

二叉树是n(n\geqslant0)个结点的有限集合,其有以下两种情况:

1)为空二叉树,即 n = 0 的时候

2)由一个根结点和两个互不相交的被称为根的左子树和右子树组成。左子树和右子树又分别是一颗二叉树。

特点:每个结点至多只有两颗子树;左右子树不能颠倒。

二叉树的五种状态

几个特殊的二叉树

满二叉树:所有叶节点都在同一层,并且所有非叶节点都有两个子节点的二叉树称为满二叉树。

完全二叉树:除了最后一层节点之外,所有节点都拥有两个子节点,并且最后一层的节点都向左对齐的二叉树称为完全二叉树。

二叉排序树:(比如找关键字为60的结点)

平衡二叉树:树上任一结点的左子树和右子树的深度之差不超过1。

回顾重点,其主要内容整理成如下内容:   

二叉树的常考性质

常见考点1:设非空二叉树中度为0、1和2的结点个数分别为 n_0,n_1,n_2 ,则 n_0 = n_2 + 1

叶子结点比二分支结点多一个

常见考点2:二叉树第i层至多有 2^{i-1} 个结点(i\geqslant1);m叉树第i层至多有 m^{i-1} 个结点(i\geqslant1)

常见考点3:高度为h的二叉树至多有 2^{h}-1 个结点(满二叉树)

高度为h的m叉树至多有 \frac{m^{h}-1}{m-1} 个结点

完全二叉树的常考性质

常见考点1:具有n个(n>0)结点的完全二叉树的高度h为 log_2(n+1)log_2n + 1

常见考点2:对于完全二叉树,可以由结点数 n 推出度为 0、1和2的结点个数为n_0n_1n_2

回顾重点,其主要内容整理成如下内容:    

二叉树的表示

在数据结构中,二叉树可以通过数组表示和链表存储表示两种方式来实现。下面分别对这两种表示方式进行简述:

数组表示

数组表示是将二叉树的节点按照某种方式存储在一个一维数组中。一般情况下,数组可以按照层次遍历的顺序存储二叉树的节点。假设根节点存储在数组下标为0的位置,那么对于任意一个节点的索引 i,其左子节点的索引为 2i+1,右子节点的索引为 2i+2。如果某个位置为空,可以使用特定的空值表示。

数组表示的优点

数组表示的优点是存储简单,通过数组索引可以快速访问到任意节点。缺点是当二叉树的形状发生改变时,需要重新调整数组的大小,可能涉及到大量的元素移动。

#include <stdio.h>
#include <stdlib.h>// 二叉树节点结构体
struct TreeNode {int val;struct TreeNode* left;struct TreeNode* right;
};// 构建二叉树的数组表示
struct TreeNode* build_binary_tree(int arr[], int size) {struct TreeNode** tree = malloc(sizeof(struct TreeNode*) * size);for (int i = 0; i < size; i++) {if (arr[i] != -1) {struct TreeNode* node = malloc(sizeof(struct TreeNode));node->val = arr[i];node->left = NULL;node->right = NULL;tree[i] = node;} else {tree[i] = NULL;}}for (int i = 0; i < size; i++) {if (tree[i] != NULL) {if (2 * i + 1 < size)tree[i]->left = tree[2 * i + 1];if (2 * i + 2 < size)tree[i]->right = tree[2 * i + 2];}}struct TreeNode* root = tree[0];free(tree);return root;
}// 测试代码
int main() {int arr[] = {1, 2, 3, 4, 5, 6, 7};int size = sizeof(arr) / sizeof(arr[0]);struct TreeNode* root = build_binary_tree(arr, size);// 输出测试结果printf("root: %d\n", root->val);printf("left child of root: %d\n", root->left->val);printf("right child of root: %d\n", root->right->val);return 0;
}

链表存储表示

链表存储表示是使用链表的方式来表示二叉树。每个节点包含一个指向其父节点的指针,一个指向其左子节点的指针,一个指向其右子节点的指针。

链表存储表示的优点

链表存储表示的优点是可以灵活地插入、删除节点而不需要移动其他节点,适用于频繁变化的二叉树结构。缺点是访问某个节点需要从根节点开始遍历,效率相对较低。

#include <stdio.h>
#include <stdlib.h>// 二叉树节点结构体
struct TreeNode {int val;struct TreeNode* left;struct TreeNode* right;
};// 构建二叉树的链表存储表示
struct TreeNode* build_binary_tree(int arr[], int size) {if (size == 0) {return NULL;}struct TreeNode* root = malloc(sizeof(struct TreeNode));root->val = arr[0];root->left = NULL;root->right = NULL;struct TreeNode** queue = malloc(sizeof(struct TreeNode*) * size);int front = 0;int rear = 0;queue[rear++] = root;int i = 1;while (i < size) {struct TreeNode* node = queue[front++];// 处理左子节点if (arr[i] != -1) {node->left = malloc(sizeof(struct TreeNode));node->left->val = arr[i];node->left->left = NULL;node->left->right = NULL;queue[rear++] = node->left;}i++;// 处理右子节点if (i < size && arr[i] != -1) {node->right = malloc(sizeof(struct TreeNode));node->right->val = arr[i];node->right->left = NULL;node->right->right = NULL;queue[rear++] = node->right;}i++;}free(queue);return root;
}// 测试代码
int main() {int arr[] = {1, 2, 3, 4, 5, 6, 7};int size = sizeof(arr) / sizeof(arr[0]);struct TreeNode* root = build_binary_tree(arr, size);// 输出测试结果printf("root: %d\n", root->val);printf("left child of root: %d\n", root->left->val);printf("right child of root: %d\n", root->right->val);return 0;
}

二叉树遍历

遍历:按照某种次序把所有结点都访问一遍。根据二叉树的递归特性要么是个空二叉树,要么就是由“根结点+左子树+右子树”组成的二叉树

根据二叉树的三种遍历规则,相关的具体案例如下:

再进行具体的练习一遍:

回顾重点,其主要内容整理成如下内容:

二叉树的层序(次)遍历

其相应的代码实现如下:

由遍历序列构造二叉树

回顾重点,其主要内容整理成如下内容: 

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

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

相关文章

遥感数据与作物模型同化:遥感数据、PROSAIL模型、DSSAT模型、参数敏感性分析、数据同化算法、模型耦合

查看原文>>>遥感数据与作物模型同化实践技术应用 基于过程的作物生长模拟模型DSSAT是现代农业系统研究的有力工具&#xff0c;可以定量描述作物生长发育和产量形成过程及其与气候因子、土壤环境、品种类型和技术措施之间的关系&#xff0c;为不同条件下作物生长发育及…

【目标检测】大图包括标签切分,并转换成txt格式

前言 遥感图像比较大&#xff0c;通常需要切分成小块再进行训练&#xff0c;之前写过一篇关于大图裁切和拼接的文章【目标检测】图像裁剪/标签可视化/图像拼接处理脚本&#xff0c;不过当时的工作流是先将大图切分成小图&#xff0c;再在小图上进行标注&#xff0c;于是就不考…

CentOS 7 使用Docker

参考资料 Docker命令大全 黑马程序员docker实操教程 &#xff08;黑马讲的真的不错 容器与虚拟机 安装 yum install -y docker Docker服务命令 启动服务 systemctl start docker停止服务 systemctl stop docker重启服务 systemctl restart docker查看docker服务状态 syste…

kafka的请求处理机制

目录 前言&#xff1a; kafak是如何处理请求的&#xff1f; 控制请求与数据类请求 参考资料 前言&#xff1a; 无论是 Kafka 客户端还是 Broker 端&#xff0c;它们之间的交互都是通过“请求 / 响应”的方式完成的。比如&#xff0c;客户端会通过网络发送消息生产请求给 B…

GBU808-ASEMI小功率开关电源GBU808

编辑&#xff1a;ll GBU808-ASEMI小功率开关电源GBU808 型号&#xff1a;GBU808 品牌&#xff1a;ASEMI 芯片个数&#xff1a;4 封装&#xff1a;GBU-4 恢复时间&#xff1a;&#xff1e;50ns 工作温度&#xff1a;-55C~150C 浪涌电流&#xff1a;200A 正向电流&#…

剑指offer

数组 剑指offer面试题3 数组中重复的数字__牛客网 (nowcoder.com) 剑指代码,称J1&#xff1a; class Solution { public:// Parameters:// numbers: an array of integers// length: the length of array numbers// duplication: (Output) t…

计算机视觉——飞桨深度学习实战-图像分类算法原理与实战

基础理论&#xff1a; 图像分类是深度学习在视觉领域第一个取得突破性成果的任务。本章首先介绍了图像分类任务的发展历程与评价指标。然后分为三个角度分别介绍了在图像分类领域具有重要地位的三种模型。第一种是基于残差网络的模型&#xff0c;本章重点介绍了ResNet、DenseN…

「滚雪球学Java」教程导航帖(更新中)

作者&#xff1a;bug菌 博客&#xff1a;CSDN | 掘金 | infoQ | 51CTO 等 简介&#xff1a;CSDN/阿里云/华为云/腾讯云/51CTO博客专家&#xff0c;博客之星Top30&#xff0c;掘金年度人气作者Top40&#xff0c;51CTO年度>博主Top12&#xff0c;掘金/InfoQ/51CTO等社区优质创…

百万架构师亲码的亿级流量下的分布式限流解决方案

在互联网应用中&#xff0c;高并发系统会面临一个重大的挑战&#xff0c;那就是大量流高并发访问&#xff0c;比如&#xff1a;天猫的双十一、京东618、秒杀、抢购促销等&#xff0c;这些都是典型的大流量高并发场景。 高并发系统限流 短时间内巨大的访问流量&#xff0c;我们…

基于javaweb的智慧社区设计与实现

目录 前言 一、技术栈 二、系统功能介绍 客户信息管理 客户信息管理 社区信息管理 车位租买支付 前台车位信息 车位预定提交 问卷调查管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理…

opengauss数据备份(docker中备份)

首先如果想直接在宿主机上进行使用gs_dump备份需要glibc的版本到2.34及以上&#xff0c;查看版本命令为 ldd --version 如图所示&#xff0c;本宿主机并不满足要求&#xff0c;所以转向在docker容器中进行备份&#xff0c; 然后进入opengauss容器中&#xff0c;命令为 docker…

ArcGIS API for JavaScript部署开发

官方快速上手教程&#xff1a;https://developers.arcgis.com/javascript/latest/ 官方 API 参考文档&#xff1a;https://developers.arcgis.com/javascript/latest/api-reference 文章目录 0.前言1.引入ArcGIS API for JavaScript部署开发1.1在线引入&#xff08;via CDN&…

C语言进阶---程序环境和预处理

C语言进阶---程序环境和预处理 前言一、程序的翻译环境、执行环境二、详解&#xff1a;C语言程序的编译链接三、预定义符号介绍四、预处理指令 #define五、宏和函数的对比&#xff08;思维导图&#xff09;六、命令定义、预处理指令 #include #undef1.命名约定2.命令行定义 七、…

[引擎开发] 杂谈ue4中的Vulkan

接触Vulkan大概也有大半年&#xff0c;概述一下自己这段时间了解到的东西。本文实际上是杂谈性质而非综述性质&#xff0c;带有严重的主观认知&#xff0c;因此并没有那么严谨。 使用Vulkan会带来什么呢&#xff1f;简单来说就是对底层更好的控制。这意味着我们能够有更多的手段…

“揭秘淘宝店铺所有商品接口:一键获取海量热销宝贝信息!“

淘宝店铺所有商品接口可以通过shop id或店铺主链接获取到整店商品&#xff0c;数据包括&#xff1a;商品ID&#xff0c;图片地址&#xff0c;店铺标题&#xff0c;优惠价&#xff0c;价格&#xff0c;销量&#xff0c;宝贝链接等整个店铺的商品。 要使用这个接口&#xff0c;需…

抄写Linux源码(Day17:你的键盘是什么时候生效的?)

回忆我们需要做的事情&#xff1a; 为了支持 shell 程序的执行&#xff0c;我们需要提供&#xff1a; 1.缺页中断(不理解为什么要这个东西&#xff0c;只是闪客说需要&#xff0c;后边再说) 2.硬盘驱动、文件系统 (shell程序一开始是存放在磁盘里的&#xff0c;所以需要这两个东…

使用弹性盒子flex对html进行布局和动态计算视口高度

使用弹性盒子flex对html进行布局的一个练习 height: calc(100vh - 4px); # vh表示视口高度的百分比&#xff0c;所以100vh表示整个视口的高度。 .mytxt { text-indent: 2em; /* 首航缩进2字符 */ line-height: 2; /* 2倍行高 */ padding: 8px; /* 内容与边框的距离 */ } …

策略模式优雅实践

1 什么是策略模式 策略模式&#xff08;Strategy Pattern&#xff09;是一种常用的面向对象设计模式&#xff0c;它定义了一系列可互相替换的算法或策略&#xff0c;并将每个算法封装成独立的对象&#xff0c;使得它们可以在运行时动态地替换。具体来说&#xff0c;策略模式定义…

Flutter学习笔记

此篇文章用来记录学习Flutter 和 Dart 相关知识 零.Dart基本数据类型 Dart 是一种静态类型的编程语言&#xff0c;它提供了一系列基本数据类型&#xff0c;用于存储和操作不同种类的数据。以下是 Dart 中的一些基本数据类型以及它们的详细介绍&#xff1a; 1. 整数类型&#…

爱国者的润学日记-十月

首先需要科学的准备面试和润。如何进行科学的准备工作呢&#xff1f; 高效的按照面试考察内容进行针对性训练&#xff0c;按 Machine-learning-interview准备保证处于专注的心态&#xff0c;如今互联网娱乐发达&#xff0c;之前即使比赛时我也是一边比赛一边看视频。之后准备面…