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

【数据结构与算法】树、二叉树的概念及结构(详解)

前言:

💥🎈个人主页:​​​​​​Dream_Chaser~ 🎈💥

✨✨专栏:http://t.csdn.cn/oXkBa

⛳⛳本篇内容:c语言数据结构--树以及二叉树的概念与结构

目录

一.树概念及结构

1.树的概念

1.1树与非树

树的特点:

非树(图)的特点:

1.2 关于树的细致概念

1.3树的表示

1.4树在实际中的运用(表示文件系统的目录树结构)

二.二叉树概念及结构

1.概念

2.现实中的二叉树:

 2.3特殊的二叉树:

2.4 二叉树的性质

证明性质2和1

习题练习


一.树概念及结构

1.树的概念

         树是一种 非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的

1.1树与非树

树的特点:
空树 -- 结点数为0的树
非空树:
  • 有一个特殊的结点,称为根结点,根节点没有前驱结点(没有父节点)

下面的两点一起理解:

  • 除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1<= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继
  • 因此,树是递归定义的。

可以理解为:

由根节点指向了各子树,子树的双亲节点又可以作为根节点,指向它们的孩子节点

非树(图)的特点:
1.除了根结点外,每个结点有且仅有一个父结点;

2.子树是不相交的
以下的这个结构是图(允许相交),不是树
注意:树形结构中,子树之间不能有交集,否则就不是树形结构

3.一棵N个结点的树有N-1条边

1.2 关于树的细致概念

下面有个✅的是比较重要的知识点

✅节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A的为6

✅叶节点或终端节点:度为0的节点称为叶节点; 如上图:B、C、H、I...等节点为叶节点

✅非终端节点或分支节点:度不为0的节点; 如上图:D、E、F、G...等节点为分支节点

✅双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图:A是B的父节点

✅孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节点

✅兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点

树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6

节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;

✅树的高度或深度:树中节点的最大层次; 如上图:树的高度为4

堂兄弟节点:双亲在同一层的节点互为堂兄弟;如上图:H、I互为兄弟节点

✅节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先

✅子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙

森林:由m(m>0)棵互不相交的树的集合称为森林

对各知识点的进一步画图解析:

  • 节点的度:与该节点直接相连的边的数量

  • 叶节点(终端节点):度为0的节点

  • 分支节点(非终端节点):度不为0的节点

  • 父节点(双亲节点):一个节点的直接前驱就是它的父节点

  • 子节点(孩子节点):一个节点的直接后继就是它的子节点
  • 兄弟节点:由同一个父节点生出来的都是互为兄弟节点
  • 树的度:一棵树中,最大的节点的度称为树的度
  • 节点的层次:从上往下数,从根开始定义起,根为第1层,根的子节点为第2层,以此类推;(默认是从1开始)
  • 树的高度(深度):树中节点的最大层次,下图的高度就是4
  • 节点的高度:从下往上数
  • 堂兄弟节点双亲在同一层的节点互为堂兄弟
  • 节点的祖先指从该节点向上追溯到根节点的路径上的所有节点,包括该节点的父节点、父节点的父节点,以此类推,直到达到根节点为止。
  • 子孙从该节点向下追溯到所有末端节点的路径上的所有节点,包括该节点的直接子节点、子节点的子节点,以此类推,直到达到叶子节点为止。
  • 森林:是由多个不相交的树组成的集合(并查集)

1.3树的表示

A: 如果明确了树的度,那么可以定义。

B、顺序表存储孩子。
 

C、双亲表示法。(每个位置只存双亲的指针或者下标) 

D、左孩子右兄弟表示法--简化树结构定义

         树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,既然保存值域,也要保存结点和结点之间的关系,实际中树有很多种表示方式如:双亲表示法,孩子表示法、孩子双亲表示法以及孩子兄弟表示法等。
我们这里就简单的了解其中最常用的孩子兄弟表示法
代码实现:
typedef int DataType;
struct Node
{struct Node* _firstChild1; // 第一个孩子结点struct Node* _pNextBrother; // 指向其下一个兄弟结点DataType _data; // 结点中的数据域
};

画图解析:

1.4树在实际中的运用(表示文件系统的目录树结构)

二.二叉树概念及结构

1.概念

一棵二叉树是结点的一个有限集合,该集合:
1. 或者为空
2. 由一个根节点加上两棵别称为左子树和右子树的二叉树组成

 从上图可以看出:

1. 二叉树不存在度大于2的结点(度为0也可以)
2. 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树
注意:对于任意的二叉树都是由以下几种情况复合而成的:

2.现实中的二叉树:

 2.3特殊的二叉树:

1. 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是 说,如果一个二叉树的层数为K,且结点总数是2^k-1 ,则它就是满二叉树。

2.完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

2.4 二叉树的性质

1、若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)个结点。
2、若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2^h-1。
3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为n2 ,则有 n0= n2+1
4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度h=log2(n+1). (ps:log2(n+1)是log以2为底,n+1为对数)
5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:

        1. i>0 i 位置节点的双亲序号: (i-1)/2 i=0 i 为根节点编号,无双亲节点
        2. 2i+1<n ,左孩子序号: 2i+1 2i+1>=n 否则无左孩子
        3. 2i+2<n ,右孩子序号: 2i+2 2i+2>=n 否则无右孩子

证明性质2和1

如何证明性质2和性质1,以下是证明过程:

习题练习

1. 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为( B)
A 不存在这样的二叉树
B 200
C 198
D 199
解析:
2.下列数据结构中,不适合采用顺序存储结构的是( A)
A 非完全二叉树
B 堆
C 队列
D 栈
解析:
顺序存储结构适合于具有连续存储空间的数据结构,其中元素按照线性顺序存储。 对于非完全二叉树,由于其结构不规则,无法通过连续的存储空间来表示。因此,非完全二叉树不适合采用顺序存储结构。
B. 堆、C. 队列、D. 栈都可以通过顺序存储结构有效地实现。堆是一种完全二叉树,可以使用数组来表示。队列和栈可以使用数组或者链表来表示,都适合顺序存储结构。
3.在具有 2n 个结点的完全二叉树中,叶子结点个数为(A )
A n
B n+1
C n-1
D n/2

和节点个数相关的公式有二:

n0 = n2 + 1,N = n0 + n1 + n2

已知总个数N为2n,那么只要知道n1即可求出n0.

这里有一个重要的结论:

        在完全二叉树中,如果节点总个数为奇数,则没有度为1的节点;如果节点总个数为偶数,只有一个度为1的节点。

                                          节点个数是偶数,只有一个度为1的节点


                                        节点个数是奇数,没有度为1的节点

2n为偶数,因此有一个度为1的节点。

2n = n0 + 1 + n2 = n0 + 1 + n0 - 1

2n = 2n0

n0 = n,故选A

4.一棵完全二叉树的节点数位为531个,那么这棵树的高度为( B)
A 11
B 10
C 8
D 12
解析:
根据性质4,h=log2(n+1),n=531,h = log2(532),找一个最接近的数就是log2(512),也就是log2(2^9),向上取整,n=10;
5.一个具有767个节点的完全二叉树,其叶子节点个数为(B)
A 383
B 384
C 385
D 386
解析:
N=767个节点数是奇数个,所以N= n0+ n2(奇数个没有度为1的节点) ,
由n0 = n2+1; N  = 2n0 - 1 ,那么n0 = (N + 1) / 2 = 384 
本篇完,如有错误,欢迎指正,感谢来访!

相关文章:

【数据结构与算法】树、二叉树的概念及结构(详解)

前言: &#x1f4a5;&#x1f388;个人主页:​​​​​​Dream_Chaser&#xff5e; &#x1f388;&#x1f4a5; ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--树以及二叉树的概念与结构 目录 一.树概念及结构 1.树的概念 1.1树与非树 树的特点&#xff1…...

函数指针数组指针(指向函数指针数组的指针)

一、什么是函数指针数组指针&#xff1f; 本质是指针&#xff0c;指向函数指针数组&#xff0c;存放函数指针数组的地址。 代码如下&#xff1a; pfArr是函数指针数组 p是函数指针数组指针 int main() {int(*pfArr[])(int, int) { Add,Sub };//函数指针数组int(*(*p)[])(int, …...

经典算法-----汉诺塔问题

前言 今天我们学习一个老经典的问题-----汉诺塔问题&#xff0c;可能在学习编程之前我们就听说过这个问题&#xff0c;那这里我们如何去通过编程的方式去解决这么一个问题呢&#xff1f;下面接着看。 汉诺塔问题 问题描述 这里是引用汉诺塔问题源自印度一个古老的传说&#x…...

博客之站项目测试报告

项目背景项目功能测试计划Bug总结升级自动化测试正常登录流程 项目背景 1&#xff1a;博客之站系统是采用前后端分离的方式来实现&#xff1b;使用MySQL、Redis数据库储存相关数据&#xff1b;同时部署到云服务器上。 2&#xff1a;包含注册页、登录页、博客列表页、个人列表页…...

k8s晋级之管理容器的计算资源

概述 在 Kubernetes 中创建工作负载时&#xff0c;您可以为 Pod 中的每一个容器指定其所需要的内存&#xff08;RAM&#xff09;大小和 CPU 数量。如果这些信息被指定了&#xff0c;Kubernetes 调度器可以更好的决定将 Pod 调度到哪一个节点。对于容器来说&#xff0c;其所需要…...

计算机竞赛 深度学习火车票识别系统

文章目录 0 前言1 课题意义课题难点&#xff1a; 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 图像识别 火车票识别系统 该项目较为新颖&#xff0c;适…...

盒子阴影和网页布局

盒子阴影 box-shadow: 10px 10px 10px 4px rgba(0,0,0,.3);//最后一个是透明度 传统网页布局的三种方式 标准流 就是按照规定好的默认方式排列 1.块级元素&#xff1a;div、hr、p、h1~h2、ul、ol、dl、form、table 行内元素会按照书顺序&#xff0c;从左到右顺序排列&#…...

Ph.D,一个Permanent head Damage的群体

一个群体 Permanent head Damage 的博士生群体 Permanent head Damage Ph.D 博士生一年级的同学们&#xff0c;不要担忧或高兴得太早&#xff0c;抱歉你们还没有经历Qualification——预备考试&#xff0c;你们暂且不能被称为博士&#xff0c;只能称自己是要努力成为博士预备…...

visual studio禁用qt-vsaddin插件更新

visual studio里qt-vsaddin插件默认是自动更新的&#xff0c;由于qt-vsaddin插件新版本的操作方式与老版本相差较大&#xff0c;且新版本不稳定&#xff0c;容易出Bug&#xff0c;所以需要禁用其自动更新&#xff0c;步骤如下&#xff1a;     点击VS2019菜单栏上的【扩展】–…...

Docker通过Dockerfile创建Redis、Nginx--详细过程

创建Nginx镜像 我们先创建一个目录&#xff0c;在目录里创建Dockerfile [rootdocker-3 ~]# mkdir mynginx [rootdocker-3 ~]# cd mynginx [rootdocker-3 ~]# vim Dockerfile Dockerfile的内容 FROM daocloud.io/library/centos:7 RUN buildDepsreadline-devel pcre-devel o…...

关于使用 uniapp Vue3 开发分享页面 语法糖 setup 开发获取ref踩坑

上代码 前端代码 <!-- 分享弹出 --> <uni-popup ref"share" type"share" safeArea backgroundColor"#fff"><uni-popup-share></uni-popup-share> </uni-popup>处理函数 import {onNavigationBarButtonTap} from…...

Springboot+vue的时间管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的时间管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的时间管理系统&#xff0c;采用M&#xff08;model&#xff0…...

企业如何实时监管员工聊天转账行为

你还在担心员工飞单、私单吗&#xff1f; 你还在担心员工辱骂删除客户吗&#xff1f; 你还在担心员工离职会带走公司客户吗&#xff1f; 你还在担心员工工作不认真&#xff0c;工作量无法统计吗&#xff1f; 。。。。。。。。 在当今互联网时代&#xff0c;企业微信的应用已…...

2.2.3.1vim + ctags + cscope + taglist

在window下,我们一般用Source Insight来查看代码而在linux下,使用vim来查看代码,vim是一个简单的文本浏览/编辑器,它可以通过插件的形式,搭建一个完全的类Source Insight环境,通过快捷键的形式,快速查看、定位变量/函数,本文就是基于vim,通过ctags+cscope+taglist+Ner…...

JAVA面经整理(4)

一)Volitaile关键字的作用: 1)保证多线程环境下共享变量的可见性&#xff0c;对于一个线程对于一个共享表变量的修改&#xff0c;其他线程可以立即看到修改之后的共享变量的值 2)可以增加内存屏障来放置多个指令之间的重排序 volatile的使用:常常用于一写多读的情况下&#xff…...

Python3数据科学包系列(一):数据分析实战

Python3中类的高级语法及实战 Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案 Python3数据科学包系列(一):数据分析实战 Python3数据科学包系列(二):数据分析实战 认识下数据科学中数据处理基础包: (1)NumPy 俗话说: 要学会跑需先…...

【LittleXi】【MIT6.S081-2020Fall】Lab: locks

【MIT6.S081-2020Fall】Lab: locks 【MIT6.S081-2020Fall】Lab: locks内存分配实验内存分配实验准备实验目的1. 举一个例子说明修改前的**kernel/kalloc.c**中如果没有锁会导致哪些进程间竞争(races)问题2. 说明修改前的kernel/kalloc.c中锁竞争contention问题及其后果3. 解释a…...

图像压缩:Transformer-based Image Compression with Variable Image Quality Objectives

论文作者&#xff1a;Chia-Hao Kao,Yi-Hsin Chen,Cheng Chien,Wei-Chen Chiu,Wen-Hsiao Peng 作者单位&#xff1a;National Yang Ming Chiao Tung University 论文链接&#xff1a;http://arxiv.org/abs/2309.12717v1 内容简介&#xff1a; 1&#xff09;方向&#xff1a;…...

C++ 类和对象篇(四) 构造函数

目录 一、概念 1. 构造函数是什么&#xff1f; 2. 为什么C要引入构造函数&#xff1f; 3. 怎么用构造函数&#xff1f; 3.1 创建构造函数 3.2 调用构造函数 二、构造函数的特性 三、构造函数对成员变量初始化 0. 对构造函数和成员变量分类 1. 带参构造函数对成员变量初始化 2. …...

Swing程序设计(5)绝对布局,流布局

文章目录 前言一、布局管理器二、介绍 1.绝对布局2.流布局总结 前言 Swing窗体中&#xff0c;每一个组件都有大小和具体的位置。而在容器中摆放各种组件时&#xff0c;很难判断其组件的具体位置和大小。即一个完整的界面中&#xff0c;往往有多个组件&#xff0c;那么如何将这…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...