数据结构-树、二叉树、查找树、平衡树

专栏原创出处:github-源笔记文件 github-源码 ,欢迎 Star,转载请附上原文出处链接和本声明。

1. 树的概念

具有 n ( n ≥ 0 ) n(n\ge 0) n(n0) 个节点的有限集称为树。

n = 0 n = 0 n=0 时称为空树;

n ≥ 1 n\ge 1 n1 时,仅有一个特定的称为根的结点,其余结点可分为 m ( m ≥ 0 ) m(m\ge 0) m(m0) 个互不相交的有限集。每一个集合本身又是一棵树,称为根的子树。

特点:树是非线性结构,数据元素具有"一对多"的逻辑关系;树中的每个元素最多有一个前驱结点,有多个后继结点。

树结构中的常见用语:

  • 节点的深度 - 从树的根节点到该节点的边数
  • 节点的高度 - 该节点和叶子之间最长路径上的边数
  • 树的高度 - 其根节点的高度

2. 二叉树

二叉树是一种更为典型的树树状结构。如它名字所描述的那样,二叉树是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”。

2.1 二叉树的遍历

  • 前序遍历:首先访问根节点,然后遍历左子树,最后遍历右子树。
  • 中序遍历:先遍历左子树,然后访问根节点,然后遍历右子树。
  • 后序遍历:先遍历左子树,然后遍历右子树,最后访问树的根节点。
  • 层级遍历:逐层遍历,二叉树的最大深度也就是层级树。

对于上述三种遍历,我们简化为,前中后只是表明遍历时「根节点的位置」,不管根在哪儿都是从左向右。每次遍历到节点时把它看做时一棵新树按刚刚的方式继续遍历。

我们可以简化为一个不需要记忆的方法:

  • 前序遍历: 左 右
  • 中序遍历:左
  • 后序遍历:左 右

1. 二叉树的关系

  • 中序遍历不能唯一确定一棵二叉搜索树;
  • 先序和后序遍历不能唯一确定一棵二叉搜索树;
  • 中序后序可以唯一确定一棵二叉树;
  • 中序先序可以唯一确定一棵二叉树。
  1. 根据「中序后序」「中序先序」构造二叉树步骤
  • 通常从先序序列或者后序序列开始,根据不同遍历方法的规律,选择合适的节点构造树;
  • 例如:先序序列的第一个节点是根节点,然后是它的左孩子,右孩子等等。后序序列的最后一个节点是根节点,然后是它的右孩子,左孩子等等;
  • 从先序/后序序列中找到根节点,根据根节点将中序序列分为左子树和右子树
  • 从中序序列中获得的信息是:如果当前子树为空(返回 None),否则继续构造子树。

3. 常见算法题

前序遍历、中序遍历、后序遍历、层级遍历、计算二叉树的最大深度。

从前序与中序遍历序列构造二叉树、从中序与后序遍历序列构造二叉树、二叉树的最近公共祖先

2.2 二叉树的类型

完美二叉树:又叫满二叉树,除叶子节点所有子节点都有左右子节点。

完全二叉树:除叶子节点所有子节点都有左右子节点。

2.3 二叉树相关算法

推荐 力扣-卡片-二叉树

3. 二叉查找树

二叉查找树(BST)是二叉树的一种特殊表示形式(也叫二叉查找树),它满足如下特性:

  1. 每个节点中的值必须大于等于存储在其左子树中的任何值。
  2. 每个节点中的值必须小于等于存储在其右子树中的任何值。

像普通的二叉树一样,我们可以按照前序、中序和后序来遍历一个二叉查找树。但是,对于二叉查找树,我们可以通过中序遍历得到一个「递增的有序序列」。因此,中序遍历是二叉查找树中最常用的遍历方法。

上述图中是一个二叉查找树,中序遍历结果为 1 2 4 6 8 10 ... 30 32 34 36

3.1 二叉查找树操作

搜索操作:

  1. 如果目标值等于节点的值,则返回节点;
  2. 如果目标值小于节点的值,则继续在左子树中搜索;
  3. 如果目标值大于节点的值,则继续在右子树中搜索。

插入操作:

与搜索操作类似,对于每个节点,我们将:

  1. 根据节点值与目标节点值的关系,搜索左子树或右子树;
  2. 重复步骤 1 直到到达外部节点;
  3. 根据节点的值与目标节点的值的关系,将新节点添加为其左侧或右侧的子节点。

删除操作:

  1. 如果目标节点没有子节点,我们可以直接移除该目标节点。
  2. 如果目标节只有一个子节点,我们可以用其子节点作为替换。
  3. 如果目标节点有两个子节点,我们需要用其中序后继节点或者前驱节点来替换,再删除该目标节点。

3.2 二叉查找树相关算法

力扣-卡片-二叉查找树

4. 平衡二叉查找树

平衡二叉查找树:是一种结构平衡的二叉查找树,即叶节点高度差的绝对值不超过 1,并且左右两个子树都是一棵平衡二叉树。

从上图可以分析如果我们计算一颗树是否是高度平衡时,自上而下的计算会重复计算子节点,如果我们自下而上计算并比较当前节点高度可以避免该问题。

有 N 个节点的平衡二叉查找树,它的高度是 l o g N logN logN

为什么是 l o g N logN logN 呢?

  • 一个高度为 h 的二叉树: 2 0 + 2 1 + ⋯ + 2 h = 2 h + 1 − 1 2^0+2^1+\cdots+2^h = 2^{h+1} -1 20+21++2h=2h+11
  • 一个有 N 个节点,且高度为 h 的二叉树: N ≤ 2 h + 1 − 1 N \leq 2^{h+1} -1 N2h+11
  • 所以: h ≥ ∣ log ⁡ 2 N ∣ h\geq|\log_2{N}| hlog2N

4.1 为什么需要用到平衡二叉查找树?

以搜索操作为例,如果二叉查找树的高度为 h,则时间复杂度为 O(h)。二叉查找树的高度的确很重要。

通过上文可知 h ≥ ∣ log ⁡ 2 N ∣ h\geq|\log_2{N}| hlog2N,所以具有 N N N个节点的二叉查找树的高度在 log ⁡ N \log{N} logN N N N 区间变化。也就是说,搜索操作的时间复杂度可以从 log ⁡ N \log{N} logN 变化到 N N N。这是一个巨大的性能差异。
所以说,高度平衡的二叉查找树对提高性能起着重要作用。

常见的平衡二叉查找树有:

4.2 实际应用

平衡二叉查找树的概念经常运用在 Set、Map 中。

比如 Java 语言中:
TreeSet 底层使用 TreeMap 实现,而 TreeMap 底层使用红黑树实现。

HashSet 底层使用 HashMap 实现,而 HashMap 底层实现了链表+红黑树实现。

参考

更多相关专栏内容汇总:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值