前言
本文主要介绍了二叉树的基本概念以及二叉树的存储结构
一、二叉树的定义
一棵二叉树是结点的一个有限集合,该集合可以是空集合,也可以是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
注意:
- 二叉树不存在度大于2的结点
- 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树
二、二叉树的几种情况
对于任意的二叉树都是由以下几种情况复合而成的
三、特殊的二叉树
1. 满二叉树
一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。
也就是说,如果一个二叉树的层数为K,且结点总数是
2
k
−
1
2^{k} - 1
2k−1,则它就是满二叉树。
2. 完全二叉树
完全二叉树是由满二叉树而引出来的,是一种效率很高的数据结构。
对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树
四、二叉树的存储结构
二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构
1. 顺序存储
即,使用数组来存储二叉树各个节点的值。
一般只有在表示完全二叉树时,会使用数组。因为其它二叉树会存在空间浪费。
二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
2. 链式存储
即,用链表来表示一棵二叉树。
一般情况下,链表中每个结点由三个域组成:数据域和左右指针域。
左右指针分别用来指向该结点左孩子和右孩子所在的链结点 。
链式结构又分为二叉链和三叉链,当前我们学习中一般都是二叉链,之后的高阶数据结构中的红黑树等会用到三叉链。
//二叉链
typedef int BTDataType;
struct BinaryTreeNode
{
BTDataType data;//当前节点的值域
struct BinaryTreeNode* pleft;//指向当前节点的左孩子
struct BinaryTreeNode* pright;//指向当前节点的右孩子
};
//三叉链
typedef int BTDataType;
struct BinaryTreeNode
{
BTDataType data;//当前节点的值域
struct BinaryTreeNode* pleft;//指向当前节点的左孩子
struct BinaryTreeNode* pright;//指向当前节点的右孩子
struct BinaryTreeNode* pparent;//指向当前节点的父节点
};
五、二叉树的性质
1.若规定根节点的层数为1,则一棵非空二叉树的第i层上结点个数最多为
2
i
−
1
2^{i-1}
2i−1。
2.若规定根节点的层数为1,则深度为h的二叉树的最大结点数是
2
i
−
1
2^{i} - 1
2i−1。
3. 对任何一棵二叉树, 如果度为0的叶结点的个数为
n
0
n_{0}
n0 , 度为2的分支结点个数为
n
2
n_{2}
n2 ,则有
n
0
n_{0}
n0=
n
2
n_{2}
n2+1。
4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h=
l
o
g
2
(
n
+
1
)
log_{2}(n + 1)
log2(n+1)。(ps:
l
o
g
2
(
n
+
1
)
log_{2}(n + 1)
log2(n+1)是log以2
为底,n+1为对数)
5. 对于具有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,则无右孩子
这样计算二叉树中某节点的左右子孩子以及父节点的方法,原因是二叉树的存储结构
总结
以上就是今天要讲的内容,本文介绍了主要介绍了二叉树的基本概念。本文作者目前也是正在学习数据结构的相关的知识,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。
最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!