树与二叉树(二叉树前传、数据结构初阶、C语言)
文章目录
- 前言
- 一、树的概念及结构
- (一)、树的概念
- (二)、树的相关概念
- (三)、树的表示
- 二、二叉树的概念及结构
- (一)、二叉树的概念
- (二)、满二叉树和完全二叉树
- (三)、二叉树的性质
- (四)、二叉树的储存结构
前言
- 在学习二叉树的实现之前,我们先学习和了解一些关于树与二叉树的重要知识,本篇博客整理了树与二叉树的概念和结构,至于对于学习二叉树来说,我总结的这些知识点足够了。如果想更加深入了解树的相关知识,这里推荐一本书:《离散数学》(第二版,屈婉玲 耿素云 张立昂)
- 绘图部分:drawio、画图板
- 代码:C语言
- 重点:二叉树
一、树的概念及结构
(一)、树的概念
树是一种非线性的数据结构,它由n(n >= 0)个有限结点组成的一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
- 有一个特殊的结点,称为根结点,根节点没有前驱结点
- 除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1 <= i <= m)又是一棵结构与树类似的子树。
- 每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。因此,树是递归定义的。
- 注意:树形结构中,子树之间不能有交集(不能有环的结构),否则就不是树形结构,如以下情况:
- 也就是说,子树是不相交的
- 除了根结点外,每个结点有且仅有一个父节点
- 一颗N个结点的树,有N-1条边
- 树在实际中的应用,比如文件系统的目录树结构
(二)、树的相关概念
- 节点的度:一个节点含有的子树的个数称为该节点的度; 如上图: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)棵互不相交的树的集合称为森林.并查集就是一颗森林
(三)、树的表示
- 树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,既然保存值域,也要保存结点和结点之间的关系,实际中树有很多种表示方式如:双亲表示法,孩子表示法、孩子双亲表示法以及孩子兄弟表示法
等。- 我们这里就简单的了解其中最常用的孩子兄弟表示法(左孩子右兄弟)。,如下:
typedef int DataType;
struct Node
{struct Node* _firstChild1; // 第一个孩子结点
struct Node* _pNextBrother; // 指向其下一个兄弟结点
DataType _data; // 结点中的数据域
};
- 以下是一个实例,用以上结构可以完美的表示一颗树,且该树是唯一的
二、二叉树的概念及结构
(一)、二叉树的概念
- 一棵二叉树是结点的一个有限集合,该集合:
- 或者为空
- 由一个根节点加上两棵别称为左子树和右子树的二叉树组成
- 从上图可以看出:
- 二叉树不存在度大于2的结点
- 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树
- 注意:对于任意的二叉树都是由以下几种情况复合而成的:
- 现实中的二叉树:
(二)、满二叉树和完全二叉树
- 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K(规定根结点层数为1),且结点总数是2^k-1 ,则它就是满二叉树。
- 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树
- 对于上面完全二叉树的定义可能不是很好理解,这里给出另一种理解方式:对于层数为K(规定根结点层数为1)的二叉树,若其K-1层为满二叉树,且第k层的结点,从左往右依次“连续”,符合左右左右……,不出现左左和右右的连续情况的二叉树即为完全二叉树,下面举例说明:
(三)、二叉树的性质
若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)个结点
若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2^h-1,即满二叉树的情况
若规定根节点的层数为1,则深度为h的二叉树的最小结点树为2^(h-1),即h-1层满二叉树再加一个左结点的情况
对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为n2 ,则有n0 = n2 +1
若规定根节点的层数为1,具有n个结点的满二叉树的深度,h = log(n+1) . (ps: h是log以2为低,n+1的对数)
- 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:
- 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
- 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
- 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子
(四)、二叉树的储存结构
二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。
- 顺序存储
顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,关于堆会在后面的博客中详细说明。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
- 链式存储
二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。链式结构又分为二叉链和三叉链,当前我们学习中一般都是二叉链,后面课程学到高阶数据结构如红黑树等会用到三叉链。
- 链式储存的定义代码如下:
typedef int BTDataType;
// 二叉链
struct BinaryTreeNode
{struct BinTreeNode* _pLeft; // 指向当前节点左孩子struct BinTreeNode* _pRight; // 指向当前节点右孩子BTDataType _data; // 当前节点值域
}
// 三叉链
struct BinaryTreeNode
{struct BinTreeNode* _pParent; // 指向当前节点的双亲struct BinTreeNode* _pLeft; // 指向当前节点左孩子struct BinTreeNode* _pRight; // 指向当前节点右孩子BTDataType _data; // 当前节点值域
}
学习记录:
- 本篇博客整理于2022.7.5
- 请多多指教
树与二叉树(二叉树前传、数据结构初阶、C语言)相关推荐
- 二叉树前中后序遍历+刷题【中】【数据结构/初阶/C语言实现】
文章目录 1. 二叉树基础操作 1.1 二叉树遍历 1.1.1 前序遍历 前序遍历(Pre-Order Traversal) 1.1.2 中序遍历 中序遍历(In-Order Traversal) 1 ...
- 数据结构初阶最终章------>经典八大排序(C语言实现)
前言: 正如标题所言,本篇博客是数据结构初阶的最终章节.但不是数据结构的最终章节!事实上,诸如AVL 树,红黑树这样高阶复杂的数据结构使用C语言非常麻烦,这些数据结构我会放在后续的C++的博客中去 ...
- 数据结构初阶(4)(OJ练习【判断链表中是否有环、返回链表入口点、删除链表中的所有重复出现的元素】、双向链表LinkedList【注意事项、构造方法、常用方法、模拟实现、遍历方法、顺序表和链表的区别)
接上次博客:数据结构初阶(3)(链表:链表的基本概念.链表的类型.单向不带头非循环链表的实现.链表的相关OJ练习.链表的优缺点 )_di-Dora的博客-CSDN博客 目录 OJ练习 双向链表--Li ...
- 数据结构初阶:二叉树
二叉树 链表和数组都是线性结构,而树是非线性的结构. 树是依靠分支关系定义出的一种层次结构.社会亲缘关系和组织结构图都可以用树来形象地表示. 1. 树 1.1 树的定义 树是 n ( n ≥ 0 ) ...
- 数据结构初阶——链式二叉树
目录 树概念及结构 树的概念 树的表示 二叉树概念及结构 概念 特殊二叉树 二叉树的性质 二叉树链式结构及实现 二叉树的简单创建 二叉树的前序遍历 二叉树中序遍历与二叉树后序遍历 求二叉树节点个数 求 ...
- 【数据结构初阶】链表(下)——带头双向循环链表的实现
目录 带头双向循环链表的实现 1.带头双向循环链表的节点类型 2.创建带头双向循环链表的节点 3.向带头双向循环链表中插入数据 <3.1>从链表尾部插入数据 <3.2>从链表头 ...
- 【数据结构初阶】第八篇——二叉树的链式结构(二叉树的前、中和后序遍历+层序遍历+链式结构的实现+相关简单的递归问题)
⭐️本篇博客我要来和大家一起聊一聊数据结构中的二叉树的链式结构的实现及相关的一些问题的介绍 ⭐️博客代码已上传至gitee:https://gitee.com/byte-binxin/data-str ...
- 数据结构初阶之二叉树——概念篇
目录 一. 树的概念及结构 1. 树的概念 2. 树的相关概念 3. 树的表示 4. 实际运用 二. 二叉树概念及结构 1. 概念 2. 完全二叉树和满二叉树 3. 二叉树的性质 三. 练习 四. 练 ...
- 数据结构初阶:八大排序
文章目录 1 排序的概念 2 插入排序 2.1直接插入排序 2.1.1 基本思想 2.1.2代码实现 2.1.3 复杂度分析 2.2 希尔排序 2.2.1 基本思想 2.2.2 代码实现 2.2.3 ...
最新文章
- java55矩阵output_leetcode 59 螺旋矩阵2 Java 用时较短-Go语言中文社区
- Android架构师亲述:我从某度外包到字节,你知道我经历了什么吗?
- 《剑指Offer》——二维数组中的查找(JZ1)C++
- Mockito 的使用
- 百度面试 php后端,2019.7最惨的三次面试经历-----百度PHP实习生面经
- sorted是python的内置函数吗_Python中的内置sorted()函数
- 若依启动sentinel教程
- 获取 python import模块的路径
- java工具类解压缩zip和rar
- Qt软件的发展历史及优势特点
- Python 中的 any(Python/any)
- 借鉴华为HiLink实现微信小程序智能配网功能
- ubuntu 批量改名
- 基于51单片机的数码录音放音系统设计
- XC3071充电IC(耐高压,带OVP)
- XML入门教程(3)
- RFID到底是什么技术
- php操作Word之com组件-获取word文档页码和更新目录
- 基于java愤怒的小鸟游戏的设计与实现
- UI设计师主要做什么?如何学好UI设计
热门文章
- 用友畅捷通T6数据升级到T+的步骤图解
- python透明的桌面时钟_透明桌面时钟-透明桌面时钟下载 v2018.07.16免费版--pc6下载站...
- 【软件工程】软件过程各种模型的理解[ 瀑布模型 快速原型模型 增量模型 螺旋模型 喷泉模型 ]
- excel导出java.lang.ArrayIndexOutOfBoundsException: 0 POI导出excel报错数组下标越界0
- HTML栅格布局container,布局栅格
- 长图预警,全网最全的23个免费无背景PNG素材网站汇总,让你有用不完的资源!!
- android编程九宫格,Android编程之九宫格实现方法实例分析
- Encountered problems while solving.Problem: nothing provides requested tophat
- springboot电子书阅读小程序毕业设计毕设作品开题报告开题答辩PPT
- angular 内置管道和自定义管道