上一篇我们学习了队列(线性表),这一篇我们来了解树,树是非线性的数据结构,树在数据结构中也很重要,这篇我们着重介绍理论,二叉树的实现放在下一篇博客,铁汁们要专心学习啊,我们开始吧!
1.认识树
数据结构中,它为什么叫树呢?因为它很形象,数据结构中的树也是很多节点,很多分叉,根据这些节点相连,组成一棵树,这是不是与我们日常生活的树很相似呢?这么描述相信大家也不是很明白,让我们先知道树的定义就会有深刻的了解了。
1.1树的结构
我们先看树的结构,结合结构看概念,体会更多
1.2树的概念
1.树的概念:树是一种非线性的数据结构,它是由n(n>=0)个有限的节点组成的一个具有 层次关系的集合。所以我们把它类比成树,但是它是根朝上,叶子朝下的。
2.树的特性:a.树有一个特殊的节点为根节点,根节点没有前驱节点
b.除根节点外,其余节点被分成N(N>0)个互不相交的集合,每个集合又是棵 结构与树类似的子树,每一棵子树的根节点有且只有一个前驱,可以有0个或 多个后继
c.树是递归的
下面的概念例子都以这棵树为例子
3.节点的度:一个节点含有的子树的个数称为该节点的度,例:A的度是6
4.叶子节点或终端节点:度为0的节点称为叶节点,例如:BCHIPQKLMN都为叶节点
5.分支节点或非终端节点:度不为0的节点,例:DEFGJ都为分支节点
6.双亲节点或父节点:若一个节点含有一个子节点,则这个节点称为其子节点的父节点,例 如:D是H的父节点
7.孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点,例:E是A的子节 点
8.兄弟节点:具有相同父节点的节点互称为兄弟节点,必须是亲兄弟才是兄弟节点,例如: BC是兄弟节点,HI就不是兄弟节点
9.树的度:一棵树中,最大的节点的度称为树的度,例如:这棵树的度为6
10.节点的层次:从根开始,根为第一层,根的子节点为第二层,以此类推,例如:这棵树 的层次是4
11.树的高度或深度:树节点的最大层次,例如:这棵树的高度为4
12.节点的祖先:从根节点到该节点所经过分支的所有节点,例如:A是所有节点的祖先,Q 的祖先是AEJ
13.子孙:以某节点为根的子树中任一节点都称为该节点的子孙,例如:所有节点都是A的子 孙,E的子孙有IJPQ
14.森林:由m(m>0)棵互不相交的树组成的集合就是森林,但我们日常学习中很少见到森林
上面加粗的概念,是我们经常会见到的。
1.3树的表示
一般有三种表示方法,但是我们一般很少实现这种普通的树,一般实现的都是二叉树。
1.C++的一种形式
//顺序表存孩子指针 struct TreeNode { int val;//节点的值 vector<struct TreeNode*>childs; };
2.存左孩子右兄弟的形式
结构:大概就是这个样子的
typedef int ADataType; struct Node { struct Node* child;//第一个孩子节点 struct Node* brother;//指向其下一个兄弟节点 ADataType val;//节点中的数据 };
3.双亲表示法形式,用数组
每个节点存父节点的数组下标
2.二叉树
上面我们介绍了普通的树的概念,然我们对树有了一定的了解,其实普通的树在我们日常中见的不多,多的还是二叉树,让我们来继续深入学习。如下图,就是一颗很标准的二叉树
2.1二叉树的结构
我们还是先看二叉树的结构,结合结构看概念:
如下图,就是一个很标准的数据结构中的二叉树
2.2二叉树的概念
1.二叉树:一棵二叉树是节点的一个有限集合,该集合或都为空,或由一个根节点加上两棵 别称为左子树和右子树的二叉树组成。
2.特点:每个节点最多有棵子树,即二叉树不存在度大于2的节点
二叉树的子树有左右之分,其子树的次序不能颠倒
3.组成:任何一棵二叉树豆油三个部分组成,根节点,左子树,右子树,如下图所示:
在树中,树是递归的,我们要涉及到一种算法,分治算法
2.3分治算法
分治算法:顾名思义,就是大问题分成类似的子问题,子问题在分成子问题,直到子问题不可再分割。就是“大事化了”
这里我们要记住在树中的这种算法,在接下来的树的前序,后序,中序遍历以及用递归实现的问题,都需要用到这种算法。
2.4特殊的二叉树
2.4.1满二叉树
1.结构:这就是一棵满二叉树
2.概念:有一个二叉树,如果每一层的节点数都达到最大值,则这个二叉树就是满二叉树, 也就是说,如果二叉树的层数为k,且节点总数是(2^k-1)则它就是一棵满二叉树。
2.4.2完全二叉树
1.结构:
2.概念:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树引出来的。
完全二叉树的前k-1层(k为二叉树的深度)与满二叉树完全相同,从第k层开始,节 点连续排列在最左侧。这意味着,除了最后一层外,其他层的节点数都达到了最大 值。在最后一层,如果存在缺失的节点,它们也是连续的,完全二叉树是满二叉树 的一种特殊形态,如果一棵二叉树是满二叉树,那么它也必定是完全二叉树。
2.5二叉树的性质
规定根节点的层数为1,假设一棵二叉树高度是h,假设一棵满二叉树共有N个节点,假设一棵完全二叉树缺失了X个节点
1.满二叉树的总节点个数:2^h-1=N
2.满二叉树的高度(深度):h=log(N+1)(以2为底)
3.完全二叉树的节点个数:2^h-1-X=N
4.完全二叉树X的范围:1~2^(h-1)-1(最后一层最起码有一个节点,否则就不是完全二叉树 了)
5.一棵非空的二叉树的第i层最多有2^(i-1)个节点
6.深度为h的二叉树的最大节点数是2^h-1(满二叉树)
7.对于任何一棵二叉树,如果度为0的叶子结点的个数为n0,度为2的分支节点的个数为n2, 则有:n0=n2+1
8.在完全二叉树中,度为1的节点最多只有1个,故度为1的节点n1可能为1,也可能为0.
以上的性质都很重要,是我们学习树经常用到的。
例如,我们在这里看一个例题:
在具有2n个节点的完全二叉树中,叶子节点的个数为( A )
A n B n+1 C n-1 D n/2
解析:我们来分析一下,完全二叉树的总节点数:n0+n1+n2=2n
根据第7条性质:n0=n2+1
则,式子可以变为n0+n1+n0-1=2n,化简得:2n0+n1=2n+1
根据第8条性质,n1可能为0,也可能为1,
当n1为1时:2n0+1=2n+1,即:n0=n
当n1为0时,2n0=2n+1,即:n0=n+1/2,节点没有一半的,故有n个叶子结点,选A
2.6二叉树的存储
接下来我们看一下二叉树是如何存储的,我们主看链式存储
2.6.1顺序存储
1.顺序存储:就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二 叉树就会有空间的浪费,现实中,只有堆才会使用数组来存储
二叉树顺序存储在物理上是一个数组,在逻辑上是一棵二叉树
2.结构:
2.6.2链式存储
1.链式存储:就是使用链表来表示一棵二叉树,用链表来指示元素的逻辑关系,通常的方法 是链表中的每一个节点由三个域组成,数据域和左右指针域,左右指针分别来 给出该节点左孩子和右孩子所在的链接点的存储位置。链式结构又分为二叉和 三叉链,在二叉树中,我们一般只用到二叉链,高阶数据结构会用到三叉链
2.结构:
2.7平衡二叉树
1.概念:平衡二叉树,也称为AVL树,是一种特殊的二叉排序树,
2.主要特点包括:
- 每个节点的左子树和右子树的高度差至多等于1。
- 它的左子树和右子树也都是平衡二叉树。
这个特性使得平衡二叉树在执行查找、插入和删除操作时提供了接近最优的性能保证,保持平衡状态是通过一系列旋转操作来实现的。
3.结构:
这就是树和二叉树了简单介绍了,它们的性质要记清楚,后续我们树的实现都要用到,铁汁们加油,我们下期再见!!!