【数据结构与算法】二叉树的基本概念

文章目录

二叉树的基本概念

定义

二叉树是一种特殊的树形结构,其特点是每个结点至多只有两颗子树,并且二叉树的子树有左右之分,其次序不可颠倒。

根据树的基本概念可知,二叉树是一棵有序树。

注意:二叉树和度为2的树、度为2的有序树不是同一概念,不要弄混淆。

如果将二叉树的左右子树颠倒,那么将产生一棵新的二叉树(与原来的二叉树不同)。即使树中结点只有一棵子树,也要区分它是左子树还是右子树。

二叉树的性质

  1. 非空二叉树上的叶结点个数等于度为2的结点个数加1,即 n 0 = n 2 + 1 n_{0}=n_{2}+1 n0=n2+1。

    理由:设总结点树为n,度为0的结点数为 n 0 n_{0} n0,度为1的结点数为 n 1 n_{1} n1,度为2的结点数为 n 2 n_{2} n2。则由树的基本概念可知, n = 0 ∗ n 0 + 1 ∗ n 1 + 2 ∗ n 2 + 1 = n 1 + 2 n 2 + 1 n=0*n_{0}+1*n_{1}+2*n_{2}+1=n_{1}+2n_{2}+1 n=0∗n0+1∗n1+2∗n2+1=n1+2n2+1(树的结点总数=结点的度数之和+1),又 n = n 0 + n 1 + n 2 = n 1 + 2 n 2 + 1 n=n_{0}+n_{1}+n_{2}=n_{1}+2n_{2}+1 n=n0+n1+n2=n1+2n2+1,所以有 n 0 = n 2 + 1 n_{0}=n_{2}+1 n0=n2+1。

  2. 非空二叉树的第k层最多有 2 k − 1 2^{k-1} 2k−1个结点( k ⩾ 1 k\geqslant1 k⩾1)。

    理由:由数学归纳法,第 1 层至多有 1 个结点 = 2 0 2^{0} 20个,第 2 层至多有 2 个 = 2 1 2^{1} 21,第 3 层至多有 4 个 = 2 2 2^{2} 22,所以第 k 层至多有 2 k − 1 2^{k-1} 2k−1个

  3. 高度为h的二叉树至多有 2 h − 1 2^{h}-1 2h−1个结点( h ⩾ 1 h\geqslant1 h⩾1)。

    理由: 2 0 + 2 1 + 2 2 + ⋯ + 2 h − 1 = 2 h − 1 2^{0}+2^{1}+2^{2}+\cdots+2^{h-1}=2^{h}-1 20+21+22+⋯+2h−1=2h−1

几种特殊的二叉树

满二叉树

假设一棵二叉树的高度为h,如果它有 2 h − 1 2^{h}-1 2h−1个结点(即二叉树每一层都含有最多的结点),那么这样的二叉树被称为满二叉树。

完全二叉树

假设一棵二叉树的高度为h,有n个结点。按层序编号时,如果它的每个结点都与高度为h的满二叉树中的结点的编号一一对应,那么我们将这样的二叉树称为完全二叉树。

举个🌰

如图,在图b中,如果6号结点没有左孩子(没有12号结点),但有右孩子。那么按层序编号时,这个右孩子的编号为12,与a中的6号结点的右孩子的编号13不对应,因此这颗二叉树不是完全二叉树。

性质

高度为h,结点个数为n的完全二叉树(按层序编号)具有以下性质:

  • 若 i ≤ ⌊ n / 2 ⌋ i\leq\lfloor n/2\rfloor i≤⌊n/2⌋,则结点i为分支结点,否则为叶结点,最后一个分支结点的编号为 i ≤ ⌊ n / 2 ⌋ i\leq\lfloor n/2\rfloor i≤⌊n/2⌋。
  • 叶结点只可能出现在层次最大的两层上。
  • 若有度为1的结点,只可能出现一个(若出现多个则必然违反完全二叉树的定义),度为1的结点只可能是编号为 i ≤ ⌊ n / 2 ⌋ i\leq\lfloor n/2\rfloor i≤⌊n/2⌋的结点。
  • 若一个结点为叶结点或其只有左孩子,那么编号大于它的结点必然是叶子结点。
  • 若n为奇数,则每个分支结点都有左右孩子(因为减去根结点后,结点个数为偶数)
  • 若n为偶数,则编号为n/2的分支结点只有左孩子,没有右孩子,编号小于n/2的结点都有左右孩子。
  • 编号为i的结点的双亲结点编号为 ⌊ i / 2 ⌋ \lfloor i/2\rfloor ⌊i/2⌋。
  • 若结点 i i i 有左右孩子,则左孩子编号为 2 i 2i 2i,右孩子编号为 2 i + 1 2i+1 2i+1。
  • 结点 i i i 所在层次(深度)为 ⌊ log ⁡ 2 i ⌋ + 1 \lfloor \log_2i \rfloor+1 ⌊log2i⌋+1。
  • 具有 n n n 个( n ⩾ 1 n \geqslant 1 n⩾1) 结点的完全二叉树的高度为 ⌈ log ⁡ 2 ( n + 1 ) ⌉ \lceil \log_2(n+1) \rceil ⌈log2(n+1)⌉或 ⌊ log ⁡ 2 n ⌋ + 1 \lfloor \log_2 n \rfloor +1 ⌊log2n⌋+1。

二叉排序树

假设有一棵二叉树,如果它满足以下三条性质:

  1. 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  3. 左、右子树也分别为二叉排序树;

我们将这样的二叉树称为二叉排序树。

个人定义:

对于一棵二叉树的任意结点来说,如果它满足:

  1. 若其左子树不为空,则左子树上的所有结点的值均小于它的值。
  2. 若右子树不空,则右子树上所有结点的值均大于它的值。

我们把这颗二叉树叫做二叉排序树。
注意:二叉排序树一定是指左边小右边大的树,如果左边大右边小,那么这个二叉树不是二叉排序树。

平衡二叉树

假设有一棵二叉树,树中任意一个结点的左子树和右子树的高度之差的绝对值不超过1,我们把这样的二叉树叫做平衡二叉树。

正则二叉树

假设有一棵二叉树,其只有度为0的结点和度为2的结点,我们把这样的二叉树叫做正则二叉树。

二叉树的存储结构

顺序存储结构

二叉树的顺序存储结构是指用一组连续的存储单元按照满二叉树的编号依次自上而下、从左往右存储结点元素。

王道写的按照完全二叉树,但是20年的408统考真题的答案是按照满二叉树的编号,所以这里我也用满二叉树。

链式存储结构

我们一般使用二叉链表来存储二叉树,二叉链表的结点至少包含3个域:数据域,左指针域,右指针域。

cpp 复制代码
// C++

template <class T>
class TreeNode{
    T data;
    TreeNode<T> *left, *right;
}

template <class T>
class Tree{
    TreeNode<T> *head;
}

在含有n个结点的二叉链表中,存在n+1个空指针域。

理由:二叉链表总共有2*n个指针,n个结点,使用了n-1个指针,所以二叉链表存在n+1个空指针域。

有时候我们也会使用三叉链表来表示二叉树,三叉链表中多余的那个指针指向双亲结点。

cpp 复制代码
// C++

template <class T>
class TreeNode{
    T data;
    TreeNode<T> *left, *right, *parent;
}

template <class T>
class Tree{
    TreeNode<T> *head;
}
相关推荐
盼海1 小时前
排序算法(五)--归并排序
数据结构·算法·排序算法
搬砖的小码农_Sky7 小时前
C语言:数组
c语言·数据结构
先鱼鲨生9 小时前
数据结构——栈、队列
数据结构
一念之坤9 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python
IT 青年9 小时前
数据结构 (1)基本概念和术语
数据结构·算法
熬夜学编程的小王9 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
liujjjiyun10 小时前
小R的随机播放顺序
数据结构·c++·算法
Reese_Cool12 小时前
【数据结构与算法】排序
java·c语言·开发语言·数据结构·c++·算法·排序算法
djk888812 小时前
.net将List<实体1>的数据转到List<实体2>
数据结构·list·.net
搬砖的小码农_Sky12 小时前
C语言:结构体
c语言·数据结构