数据结构与算法-树形结构

359 阅读8分钟

一.树形结构

  • 树形结构分为二叉树跟多叉树,二叉树是每个节点为2,多叉树是每个节点大于2;
  • 节点,根节点,父节点,子节点,兄弟节点
  • 一棵树可以没有任何节点,称为空树
  • 一棵树可以只有1个节点,也就是只有根节点
  • 子树,左子树,右子树
  • 节点的度(defree):子树的个数
  • 树的度:所有节点度中的最大值
  • 叶子节点(leaf):度为0的节点
  • 非叶子节点:度不为0的节点
  • 层数(level):根节点在第1层,根节点的子节点在第2层,以此类推
  • 节点的深度(depth):从根节点到当前节点的唯一路径上的节点总数
  • 节点的高度(height):从当前节点到最远叶子节点的路径上的节点总数
  • 树的深度:所有节点深度中的最大值
  • 树的高度:所有节点高度中的最大值
  • 树的高度等于树的深度

二.有序树,无序树,森林

  • 1.有序树
    • 树中任意节点的子节点之间有顺序关系
  • 2.无序树
    • 书中任何节点的子节点之间没有顺序关系
    • 也称为自由树
  • 3.森林
    • 由m棵互不相交的树组成的集合

三.二叉树(Binary Tree)

  • 1.二叉树的特点
    • 每个节点的度最大为2(最多拥有2棵子树)
    • 左子树跟右子树是有顺序的
    • 即使某节点只有一棵子树,也要区分左右子树
    • 二叉树是有序树

二叉树.png

特殊有序树.png

  • 2.二叉树的性质
    • 非空二叉树的第i层,最多有2^(i-1)个节点(i>=1)

    • 在高度为h的二叉树上最多有2^(h-1)个节点)(h>=1)

    • 对于任何一棵非空二叉树,如果叶子节点个数为n0,度为2的节点个数为n2,则有:n0=n2 + 1

    • 假设度为1的节点个数为n1,那么二叉树的节点总数n = n0 + n1 + n2

    • 二叉树的变数T=n1 + 2 * n2 = n - 1 = n0 + n1 + n2 - 1

二叉树.png

三.真二叉树(Proper Binary Tree)

  • 1.真二叉树:所有节点的度要不为0,要不为2(不能出现度为1)

真二叉树.png

四.满二叉树(Full Binary Tree)

  • 1.满二叉树:所有节点的度要不为0,要不为2,且所有叶子节点都在最后一层
  • 2.在同样高度的二叉树中,满二叉树的叶子节点数量是最多的,总节点数量也是最多的
  • 3.满二叉树一定是真二叉树,真二叉树不一定是满二叉树
  • 4.满二叉树一定是完全二叉素,完全二叉树不一定是满二叉树
  • 5.假设满二叉树的高度为h(h>=1),那么
    • 第i层的节点总数:2^(h-1)
    • 叶子节点的总数:2^(h-1)
    • 总节点数为n = 2^0 + 2^1 + 2^2 +...+ 2^(h-1) = 2^h -1

满二叉树.png

五.完全二叉树

  • 1.概念
  • 完全二叉树:叶子节点只会出现在最后2层,且最后1层的叶子节点都靠左对齐
  • 完全二叉树从根节点至倒数第2层是一棵满二叉树
  • 满二叉树是完全二叉树,完全二叉树不一定是满二叉树

完全二叉树.png

  • 2.完全二叉树的性质

  • 度为1的节点只有左子树

  • 度为1的节点要不0个,要不1个

  • 同样节点数量的二叉树,完全二叉树的高度最小

  • 假设完全二叉树的高度为h(h>=1),那么

    • 至少有2^(h-1)个节点(2^0 + 2^1 + 2^2 +...+ 2^(h-2) + 1)
    • 最多有2^h - 1个节点(2^0 + 2^1 + 2^2 +...+ 2^(h-1) 满按满二叉树节点算)
    • 总节点数量为n = 2^(h-1) <= n <= 2^h
  • 一棵有n个节点的完全二叉树(n > 0),从上到下,从左到右对节点从1开始进行编号,对任意第i个节点

    • 如果i=1,它是根节点
    • 如果i>1,它的父节点编号为floor(i/2)
    • 如果2 * i <= n , 它的左子节点编号为2 * i
    • 如果2 * i + 1 <= n , 它的右子节点编号为2 * i + 1
    • 如果2 * i + 1 >= n , 它无右子节点

    完全二叉树.png

  • 一棵有n个节点的完全二叉树(n > 0),从上到下,从左到右对节点从0开始进行编号,对任意第i个节点

    • 如果i=0,它是根节点
    • 如果i>0,它的父节点编号为floor((i - 1)/2)
    • 如果2 * i + 1 <= n - 1 , 它的左子节点编号为2 * i + 1
    • 如果2 * i + 2 <= n - 1, 它的右子节点编号为2 * i + 2
    • 如果2 * i + 1 > n - 1 , 它无左子节点

完全二叉树.png

  • 3.练习-完全二叉树叶子节点数

求叶子节点练习.png

总结如下:

总结1.png

总结2.png

所以最后的答案为:

求解答案.png

对于二叉树,国外给出的说法如下:

image.png

四. 二叉树搜索

  • 1.假设有这么一个需求,在n个动态的整数中搜索某个整数?(查看其是否存在)
  • 假设使用动态数组存放元素,从第0个位置开始遍历搜索,平均时间复杂度为O(n)

image.png

  • 如果维护一个有序的动态数组,使用二分搜索,最坏的时间复杂度:O(logn),但是添加,删除的平均时间复杂度为O(n)

image.png

  • 针对这个需求,可以使用二叉搜索树,其添加,删除,搜索的最坏时间复杂度可优化为:O(logn)

五.二叉搜索树(Binary Search Tree)

  • 1.二叉搜索树概念
    • 二叉搜索树是二叉树中的一种,是应用非常广泛的一种二叉树,英文简称为BST,又名二叉查找树,二叉排序树
    • 任意一个节点的值都大于其左子树所有节点的值
    • 任意一个节点的值都小于其右子树所有节点的值
    • 它的左右子树也是一棵二叉搜索树
  • 二叉搜索树可以大大提高搜索的效率
  • 二叉搜索树存储的数据必须具备可比较性,
    • 比如int double等

    • 如果是自定义类型,需要指定比较方式

    • 不允许为null

image.png

  • 2.二叉搜索树的接口设计

image.png

  • 对于现在的二叉搜索树来说,他的元素没有索引的概念

  • 3.add

image.png

  • 4.二叉树遍历
  • 根据节点访问顺序不同,二叉树常见遍历方式有4种
    • 前序遍历(Preorder Traversal)根左右
    • 中序遍历(Inorder Traversal)左根右
    • 后序遍历(Postorder Traversal)左右根
    • 层序遍历(Level Order Traversal)

下面的遍历循环都是以这个二叉树讲的

image.png

image.png

image.png

image.png

image.png

  • 5.练习-计算二叉树高度
  • 6.练习-判断完全二叉树 层序遍历 思路1:
    image.png

image.png

思路2: image.png

image.png

  • 7.练习-翻转二叉树 翻转:将所有节点的左右子树都交换

image.png

前序遍历方法
image.png

中序遍历方法

image.png

    1. 根据遍历结果重构二叉树

Snip20210817_9.png

image.png

image.png

  • 9.前驱节点(predecessor)

image.png

  • 10 后继节点(successor)

image.png

  • 11.删除节点-叶子节点

image.png

  • 12.删除节点-度为1的节点

image.png

  • 13.删除节点-度为2的节点

image.png

  • 14.二叉搜索树的时间复杂度
  • 二叉搜索树的插入,删除,搜索时间复杂度如下,如果退换成链表,则跟链表时间复杂度一样,当n越大,二叉搜索树的时间复杂度越小,链表时间复杂度越大

image.png

image.png

六.平衡二叉搜索树

  • 1.平衡:当节点数量固定时,左右子树的高度越接近,这棵二叉树就越平衡(高度越低)

image.png

  • 2.理想平衡
  • 完全二叉树跟满二叉树 是接近理想平衡状态的二叉树

image.png

  • 3.改进二叉搜索树?
  • 添加和删除元素数值大小没法控制,但是可以德国删除,添加操作后,将二叉树尽量调整为平衡二叉树

image.png

  • 4.平衡二叉搜索树

image.png

七.AVL树

  • 平衡因子(Balance Factor):某结点的左右子树的高度差
  • 1.AVL树 概念
  • 平衡二叉搜索树之一
  • AVL树每个节点的平衡因子只可能为:1/0/-1 (绝对值 <= 1,如果超过1 称为“失衡”)
  • 每个节点的左右子树高度差不超过1
  • 搜索,添加,删除的时间复杂度为O(logn)

image.png

image.png

  • 2.二叉树,二叉搜索树,AVL树,红黑树 之间的继承关系如下:

image.png

  • 3.添加导致的失衡

image.png

  • 3.1LL-右旋转(单旋)-解决失衡方式之一

image.png

  • 3.2RR-左旋转(单旋)-解决失衡方式之二

image.png

  • 3.3LR-RR左旋转,LL右旋转(双旋)- 解决失衡方式之三

image.png

  • 3.4RL-LL右旋转,RR左旋转(双旋)-解决失衡方式之四

image.png

  • 3.5统一旋转操作 image.png

  • 4.删除导致的失衡

image.png

  • 4.1 LL-右旋转 (单旋)

image.png

  • 4.2 RR-左旋转(单旋)

image.png

  • 4.3 LR-RR左旋转,LL右旋转(双旋)

image.png

  • 4.4 RL-LL右旋转,RR左旋转(双旋)

image.png

如果绿色节点不存在,更高层的祖先节点可能也会失衡,需要再次恢复平衡,然后又可能导致更高层的祖先节点失衡。极端情况下,所有祖先节点都需要进行恢复平衡的操作,共(logn)次调整。

  • 5 AVL树总结

image.png

对于普通二叉树搜索来说,AVL树的效率是最高的

八.B树(B-tree,B-树)

  • 1.B树概念
    • 是一种平衡的多路搜索树,多用于文件系统,数据库的实现
    • 1个节点可以存储超过2个元素,可以拥有超过2个子节点
    • 拥有二叉搜索树的一些性质
    • 平衡,每个节点的所有子树高度一致
    • 比较矮

image.png

  • 2.m阶B树的性质(m>=2)

image.png

  • 3.B树 vs 二叉搜索树

image.png

将二叉搜索树中某些父子节点进行合并就能变成一个B树,上图合并结果如下:

image.png

image.png

  • 4.B树搜索

image.png

  • 5.添加

image.png

节点存储元素超过m阶二叉树,

image.png

  • 6.添加-上益处的解决方式 image.png

  • 7.删除-非叶子节点/叶子节点

image.png

  • 8.删除-下溢的解决方式

image.png

九.红黑树(Red Black Tree)

  • 1.红黑树概念
    • 一种自平衡的二叉搜索树,也叫平衡二叉B树(Symmetric Binary B-tree),不需要靠平衡因子来维护平衡,通过下面5种情况来维护平衡
  • 2.红黑树性质
    • 节点Red 或者 Black

    • 根节点 必须是 Black

    • 叶子节点(外部节点,空节点)都是 Black

    • Red 节点的子节点是 Block

    • 根节点叶子节点 的所有路径和那个不能有2个连续的 Red 节点

    • 任一节点叶子节点 的所有路径都包涵相同数目的 Black 节点

image.png

  • 2.红黑树的等价变换

image.png

  • 3.认识英文单词 image.png

  • 4.添加

image.png

image.png

  • 4.1添加-修复性质4-LL/RR

image.png

  • 4.2添加-修复性质4-LR/RL

image.png

  • 4.3添加-修复性质4-上溢-RL

Snip20210826_12.png

  • 4.4添加-修复性质4-上溢-LL

Snip20210826_11.png

  • 4.5添加-修复性质4-上溢-RR

Snip20210826_10.png

  • 5.删除

image.png

image.png

  • 5.1 删除-拥有1个RED子节点的Black节点

image.png

  • 5.2 删除-Black叶子节点-sibling为Black

image.png

  • 5.4 删除-Black叶子节点-sibling为Black

image.png