二叉树 Implemented with C++

Tree 树

Definition 定义

树是 n ( n ≥ 0 ) n(n\ge0) n(n0) 个结点的有限集合,当 n = 0 n=0 n=0 时,称为空树。对于任意一棵树都有:

  • 有且仅有一个根结点(root)
  • 从根节点到其他结点有且只有一条路径(这是图论中对于树的定义,事实上,树是有向图的一种)

这是一种非递归的定义,而显然树是一种递归的结构,我们可以用递归的方式对树进行定义:

  • n ≥ 1 n\ge1 n1 时,其余结点可以分为 m > 0 m>0 m>0 个互不相交的有限集合 T 1 , T 2 , T 3 , … , T m T_{1},T_{2},T_{3},\dots,T_{m} T1,T2,T3,,Tm,这些集合本身都是一棵树,并且称为根结点的子树

这样的递归结构具有以下的特点:

  • 除了根结点之外的所有结点有且只有一个前驱结点
  • 每个结点都有零个或者多个结点

Some Important Terminology 一些重要的概念

关于结点关系:

TerminologyExplanation
父结点(parent node)该结点的前驱结点称为该结点的父结点
子结点(children node)该结点的后继结点成为该结点的子结点
兄弟结点(sibling node)具有相同父结点的结点互为兄弟结点

关于结点的一些概念:

TerminologyExplanation
结点的度一个结点的子结点的度,结点的最大度数是树的度数
分支结点(非终端结点)度数不为0的点
叶子结点(终端结点)度数为0的结点(即只有前驱结点,但是没有后继结点,从图论的角度来说,这样的结点入度(in degree)为1,出度(out degree)为0)

关于树的一些概念:

TerminologyExplanation
结点的层次从根结点开始是第一层(或者是第零层,取决于具体要求)
结点的深度从根结点开始,逐层累加
结点的高度从最后一层开始,逐层累加
树的高度(同时也是树的深度)树的最大层数

从树的结点次序来看,还可以分为:有序树无序树

Some Important 一些重要的性质

树具有一下基本的性质:

  • 如果树的结点度数是 k k k ,则树的结点数量为: n = k + 1 n=k+1 n=k+1(考虑一个无环图,那么这个图的结点数量肯定是边数量加 1 1 1,而一个结点的一个度数对应一条边,所以结点数量就是总度数加 1 1 1
  • 度为 m m m 的树种第 i i i 层上至少有 m i − 1 m^{i-1} mi1 个结点,
  • 高度为 h h h,度为 m m m 的树至多有 n = 1 + m + m 2 + ⋯ + m h − 1 = ( m h − 1 ) / ( m − 1 ) n=1 + m + m^{2} + \dots + m^{h-1}=(m^{h}-1)/(m-1) n=1+m+m2++mh1=(mh1)/(m1) 个结点,例如我们熟悉的二叉树的结点总数为 ( 2 h − 1 ) / ( 2 − 1 ) = 2 h − 1 (2^{h}-1)/(2-1)=2^{h}-1 (2h1)/(21)=2h1
  • n n n 个结点的 m m m 叉树的高度至少为 log ⁡ m ( n ( m − 1 ) + 1 ) \log_{m}(n(m-1)+1) logm(n(m1)+1)

Binary Tree 二叉树

Definition 定义

二叉树即树的度数为2,有左右子树之分,不能任意颠倒,通常类似一棵度为 2 2 2 的有序树,区别在于:

  • 二叉树可以为 ∅ \varnothing ,但是度为 2 2 2 的有序树至少有 3 3 3 个结点
  • 当一个结点只有一个孩子的时候,对于有序树的结点来说,无需区分左右,而对于二叉树来说,这个子结点必须区分左右,结点次序是确定的

一些特殊的二叉树:

  • 满二叉树:树的每一层的结点数量都是该层的最大结点数量
  • 完全二叉树:满二叉树一定是完全二叉树,但是完全二叉树不一定是满二叉树。完全二叉树是根节点和分支结点的度都为 2 2 2 的树

Properties 性质

二叉树的性质:

  • 非空二叉树的叶子结点数 n 0 n_{0} n0 等于度为 2 2 2 的结点数 n 2 n_{2} n2 加一,即: n 0 = n 2 + 1 n_{0}=n_{2}+1 n0=n2+1
    证 明 : 由 树 的 性 质 有 : 结 点 总 数 N = 1 ⋅ n 1 + ⋯ + m ⋅ n m , 其 中 m 是 树 的 度 ( 即 结 点 最 大 度 数 ) 又 ∵ N = n 1 + ⋯ + n m ∴ 对 于 二 叉 树 , 有 { N = n 0 + n 1 + n 2 N = 0 ⋅ n 0 + 1 ⋅ n 1 + 2 ⋅ n 2 + 1 = n 1 + 2 ⋅ n 2 + 1 ∴ n 0 = n 2 + 1 \footnotesize \begin{aligned} &证明:\\ &由树的性质有:结点总数 N=1\cdot n_{1}+\cdots+m\cdot n_{m},其中 m 是树的度(即结点最大度数)\\ &又\because N=n_{1}+\cdots+n_{m}\\ &\therefore 对于二叉树,有 \begin{cases} &N=n_{0}+n_{1}+n_{2}\\ &N=0\cdot n_{0}+1\cdot n_{1}+2\cdot n_{2}+1=n_{1}+2\cdot n_{2}+1 \end{cases}\\ &\therefore n_{0}=n_{2}+1 \end{aligned} N=1n1++mnmmN=n1++nm{N=n0+n1+n2N=0n0+1n1+2n2+1=n1+2n2+1n0=n2+1
  • i i i 层最多有 2 i − 1 2^{i-1} 2i1 个结点
  • 高度为 h h h 的二叉树至多有 2 h − 1 2^{h} - 1 2h1 个结点

二叉树的顺序存储

存储结点的顺序:

  • 自上而下
  • 从左到右

即,一层一层的存储,先存储第一层,也就是树根,在数组的第一个位置,然后从左到右存储下一层,以此类推,这样存储,则有:

  • 结点 a [ i ] a[i] a[i] 的两个子结点的位置为 a [ 2 i + 1 ] , a [ 2 i + 2 ] a[2i+1],a[2i+2] a[2i+1],a[2i+2]
  • 结点 a [ i ] a[i] a[i] (如果i不等于 0 0 0)的父结点为 a [ ( i − 1 ) / 2 ] a[(i-1)/2] a[(i1)/2]
    当然,你也可以从数组下标为1的位置开始存储,这样在下标计算的时候可以更加简单

采用顺序存储结构在存储满二叉树和完全二叉树的时候,空间利用率较高,既可以直接访问,又可以通过下标确定相关结点;但是最坏的情况下,一棵高度为 h h h,包含 h h h 个结点的二叉树需要占据 2 H − 1 2^{H}-1 2H1 个存储单元。并且,顺序存储的二叉树不适合进行插入删除操作

二叉树的链式存储

typedef struct Node{
	ElementType value;
	Node* left;
	Node* right;
	Node(ElementType value_, left_ = NULL, right_ = NULL)
		:value(value_), left(left_), right(right_){}
}Node;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值