既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
- 有且仅有一个特定的结点称为👉根(Root)👈的结点
- 当
n
1
n>1
n>1时,其余结点可分为
m
(
m
0
)
m(m>0)
m(m>0)个互不相交的有限集
T
1
、
T
2
、
⋅
⋅
⋅
⋅
⋅
、
T
m
T1、T2、·····、Tm
T1、T2、⋅⋅⋅⋅⋅、Tm,其中每一个集合本身又是一棵树,并且称为根的👉子树(SubTree)👈
树的结构定义是一个递归的定义,即在树的定义中又用到树的概念,递归是树固有的特性。在树型结构中,除了根结点以外,任何一个结点有且仅有一个前驱,每个结点可以有0个或多个后继。结点数为0的树又称之为空树。
🚢树的基本术语
树的结点包含一个数据元素及若干指向其子树的分支。结点拥有的子树数称为结点的度(Degree)。
📌以上图为例,结点D的度为3,因为结点D有三条分支结构;依次列举,结点C的度为1,结点B的度为2等等
度为0的结点称为叶子(Leaf)结点或终端结点。
📌以上图为例,结点K、L、F、G、M、I、J都是度为0的结点,所以他们也被称为叶子结点或终端结点
度不为0的结点称为非终端结点或分支结点。除根节点外,分支结点也称为内部结点。
📌以上图为例,结点B、C、D、E、H的度都不为零,所以他们称为非终端结点或分支结点
树的度是树内各结点的度的最大值。
📌以上图为例,在整棵树中,结点中度的最大值是3,所以树的度就为3
结点的子树的根称为该结点的孩子(Child),相应地,该结点称为孩子的双亲(Parent)。
📌以上图为例,结点B的孩子结点为E和F,反之,结点B也是结点E、F的双亲结点
同一个双亲的孩子之间互称兄弟(Sibling)。
📌以上图为例,结点H、I、J的双亲为同一个结点D,所以结点H、I、J互为兄弟结点
结点的祖先是从根到该结点所经分支上的所有结点,反之,以某结点为根的子树中的任一结点都称为该结点的子孙。
📌以上图为例,结点G的祖先就为结点A和C,反之,结点C的子孙就为结点G
结点的层次(Level) 是从根开始定义的,根为第一层,根的孩子为第二层✍(自上往下数)
📌以上图为例,结点G的层次为3
树中结点的最大层次称为树的深度(Depth) 或高度✍(其实就是整棵树总共有多少层)
📌以上图为例,树的深度或高度为4
👉结点数 = 总度数 + 1👈
📌以上图为例,结点A的度数为3;结点B的度数为2;结点C的度数为1,结点D的度数为3;结点E的度数为2;结点H的度数为1;其余结点K、L、F、G、M、I、J的度数为0,所以这棵树的结点数就等于:
📌T结点数 = 3+2+1+3+2+1+1;最后结果为13
🚢有序树和无序树
有序树——逻辑上看,树中结点的各子树从左至右是有次序的,不能互换
无序树——逻辑上看,树中结点的各子树从左至右是无次序的,可以互换
🚢森林
👉森林(Forest)👈是
m
(
m
=
0
)
m(m>=0)
m(m>=0)棵互不相交的树的集合,对树中的每个结点而言,其子树的集合即为森林。
📌森林可以为空
🚀二叉树
🚢二叉树的定义
👉二叉树(Binary Tree)👈是另一种树型结构,它的特点是每个结点至多只有两棵子树(✍即二叉树中不存在度大于2的结点
),并且,二叉树的子树有左右之分,其次序不能任意颠倒。
二叉树或为空,或是由一个根结点加上两棵分别称为左子树和右子树的、互不相交的二叉树构成,由于这两棵子树也是二叉树,则由二叉树的定义,它们也可以是空树。由此,二叉树可以有5中基本形态。
🚢二叉树的性质
✨二叉树具有下列重要特性
🚗性质一: 在二叉树的第
i
i
i 层上之多有 2i-1 个结点(
i
=
1
i>=1
i>=1)
🚗性质二: 深度为
k
k
k 的二叉树之多有 2k-1 个结点(
k
=
1
k>=1
k>=1)
🚗性质三: 对任何一棵二叉树T,如果其终端结点数为
n
0
n0
n0,度为2的结点数为
n
2
n2
n2,则有
n
0
=
n
2
1
n0=n2+1
n0=n2+1
🚢满二叉树
一棵深度为
k
k
k 且有 2k-1 个结点的二叉树称为👉满二叉树👈,这种树的✍特点是每一层上的结点数都是最大结点数,只有最后一层是叶子结点且不存在度为1的结点
🚢完全二叉树
深度为
k
k
k 的,有
n
n
n 个结点的二叉树,当且仅当其每一个结点都与深度为
k
k
k 的满二叉树中编号从1至
n
n
n 的结点一一对应时,称之为👉完全二叉树👈,✍在一棵完全二叉树中只有最后两层可能为叶子结点,且最多只有一个度为1的结点。
✨完全二叉树的两个重要特性:
🚗特性一: 具有
n
n
n个结点的完全二叉树的深度为
l
o
g
2
n
log2n
log2n向下取整+1
🚗特性二: 如果对一棵有
n
n
n个结点的完全二叉树(其深度为
l
o
g
2
n
log2n
log2n向下取整+1)的结点按层序编号(从第一层到第
l
o
g
2
n
log2n
log2n向下取整+1层,每层从左到右),则对任一结点
i
(
1
<
=
i
<
=
n
)
i(1<=i<=n)
i(1<=i<=n),有以下结论:
如果
i
=
1
i=1
i=1,则结点
i
i
i是二叉树的根,无双亲,如果
i
1
i>1
i>1,则双亲(Parent)为结点
i
/
2
i/2
i/2向下取整;
如果
2
i
n
2i>n
2i>n,则结点i无左孩子(结点
i
i
i为叶子结点);否则其左孩子(Lchild)是结点2i;
如果
2
i
1
n
2i+1>n
2i+1>n,则结点i无右孩子,否则其右孩子(Rchild)是结点
2
i
1
2i+1
2i+1;
🚗特性三: 满二叉树是一种特殊的完全二叉树,但完全二叉树不一定是满二叉树
🚢二叉排序树
左子树上所有结点的关键字均小于根结点的关键字,右子树上所有结点的关键字均大于根结点的关键字,左子树和右子树又各是一棵二叉排序树。
✨二叉排序树用于元素的搜索和排序。
🚢平衡二叉树
树上任何一个结点的左子树和右子树的深度之差不超过1。
✨平衡二叉树能有更高的搜索效率。
🚢二叉树的存储结构
🌈顺序存储结构
按照顺序存储结构的定义,用一组地址连续的存储单元依次✍自上而下、从左往右
存储完全二叉树的结点元素,即将完全二叉树上编号为
i
i
i的结点元素存储在如上定义的一维数组中下标为
i
−
1
i-1
i−1的分量中。
//二叉树的顺序存储表示
#define MaxSize 100 //二叉树的最大结点数
struct TreeNode
{
ElemType value; //结点中的数据元素
bool isEmpty; //结点是否为空
};
//定义一个长度为MaxSize的数组t,按照从上而下,从左至右的顺序依次存储二叉树中的各个结点
TreeNode t[MaxSize];
对于一般二叉树,则应将其每个结点与完全二叉树上的结点相对照,存储在一维数组中的对应分量中。✍顺序存储结构更多仅适用于完全二叉树的存储。
🌈链式存储结构
由二叉树的定义得知,二叉树的结点由一个数据元素和分别指向其左、右子树的两个分支构成,则表示二叉树的链表中的结点至少包含三个域:👉数据域👈和👉左、右指针域👈。有时,为了便于找到结点的双亲,则还可以在结点结构中增加一个指向其双亲结点的指针域。 利用这两种结点结构所得的二叉树的存储结构分别称之为👉二叉链表👈和👉三叉链表👈。
//二叉树的二叉链表存储表示
typedef struct BiTNode
{
TElemType data; //数据域
struct BiTNode \*lchild, \*rchild //左右孩子指针
}BiTNode,\*BiTree;
🚢二叉树的遍历
在二叉树的一些应用中,常常要求在树中查找具有某种特征的结点,或者对树中全部结点逐一进行某种处理。回顾二叉树的递归定义可知,二叉树是由三个基本单元组成:根节点、左子树和右子树,因此,✍二叉树的遍历分为先(根)序遍历、中(根)序遍历、后(根)序遍历和层次遍历。
🚩先(根)序遍历二叉树的操作定义为(根左右):
若二叉树为空,则空操作,否则:
- 访问根结点;
- 先序遍历左子树;
- 先序遍历右子树;
🚩中(根)序遍历二叉树的操作定义为(左根右):
若二叉树为空,则空操作,否则:
- 中序遍历左子树;
- 访问根结点;
- 中序遍历右子树;
🚩后(根)序遍历二叉树的操作定义为(左右根):
若二叉树为空,则空操作,否则:
- 后序遍历左子树;
- 后序遍历右子树;
- 访问根结点;
🚩层次遍历二叉树的操作定义为:
- 初始化一个队列;
- 根结点入队;
- 若队列非空,则队头结点出队,访问该结点,并将其左、右孩子插入队尾;
- 重复上一步,直到队列为空
🚢线索二叉树
在遍历二叉树时,要想找到某个结点的前驱和后继的信息,得运用二叉树已知的遍历方法从头开始遍历,然后在遍历的过程中动态获取其结点的前驱和后继的信息,那有没有一种方法是已知该结点就已经知道其前驱和后继的信息了呢?答案肯定是有的,为了解决二叉树遍历时所存在的一些问题,线索二叉树也孕育而生。那什么是👉线索二叉树👈呢?
简单理解就是✍利用空链域来存放结点的前驱和后继的信息,方便寻找前驱结点和后继结点,提高遍历效率
。因为n个结点的二叉树,有
n
1
n+1
n+1个空链域,所以可以利用这些空链域来记录前驱,后继的信息。**若结点有左子树,则其
l
c
h
i
l
d
lchild
lchild域指示其左孩子,否则令
l
c
h
i
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
始化一个队列;
- 根结点入队;
- 若队列非空,则队头结点出队,访问该结点,并将其左、右孩子插入队尾;
- 重复上一步,直到队列为空
🚢线索二叉树
在遍历二叉树时,要想找到某个结点的前驱和后继的信息,得运用二叉树已知的遍历方法从头开始遍历,然后在遍历的过程中动态获取其结点的前驱和后继的信息,那有没有一种方法是已知该结点就已经知道其前驱和后继的信息了呢?答案肯定是有的,为了解决二叉树遍历时所存在的一些问题,线索二叉树也孕育而生。那什么是👉线索二叉树👈呢?
简单理解就是✍利用空链域来存放结点的前驱和后继的信息,方便寻找前驱结点和后继结点,提高遍历效率
。因为n个结点的二叉树,有
n
1
n+1
n+1个空链域,所以可以利用这些空链域来记录前驱,后继的信息。**若结点有左子树,则其
l
c
h
i
l
d
lchild
lchild域指示其左孩子,否则令
l
c
h
i
[外链图片转存中…(img-eW69oKHW-1715479792819)]
[外链图片转存中…(img-FKeuf9Vu-1715479792819)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!