【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)

文章目录

    • 5.3 二叉树的遍历和线索二叉树
      • 5.3.1 二叉树的遍历
        • 1. 先序遍历
        • 2. 中序遍历
        • 3. 后序遍历
        • 4. 遍历算数表达式树
        • 5. 层次遍历
        • 6. 由遍历序列构造二叉树
      • 5.3.2 线索二叉树
        • 1. 引言
        • 2. 线索二叉树的存储结构
        • 3. 手算画出线索二叉树
        • 4. 二叉树的线索化(代码)
          • (1) 中序线索化
          • (2) 先序线索化
          • (3) 后序线索化
          • (4) 小结
        • 5. 线索二叉树找前驱/后继(代码)
          • (1) 中序线索二叉树找前驱、后继
          • (2) 先序线索二叉树找前驱、后继
          • (3) 后序线索二叉树找前驱、后继
      • 5.3.3 小结

5.3 二叉树的遍历和线索二叉树

5.3.1 二叉树的遍历

遍历:按照某种次序把所有结点都访问一遍。
层次遍历:基于树的层次特性确定的次序规则。
先/中/后序遍历:基于树的递归特性确定的次序规则。(其中 ‘序’ 指的是根节点的位置)
二叉树的递归特性: ①要么是个空二叉树 ②要么就是由“根节点+左子树+右子树”组成的二叉树。

1. 先序遍历

先序遍历(PreOrder)的操作过程如下:

  1. 若二叉树为空,则什么也不做;
  2. 若二叉树非空: ①访问根结点; ②先序遍历左子树; ③先序遍历右子树。
    【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第1张图片

2. 中序遍历

中序遍历(InOrder)的操作过程如下:

  1. 若二叉树为空,则什么也不做;
  2. 若二叉树非空: ①先序遍历左子树; ②访问根结点; ③先序遍历右子树。
    【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第2张图片

3. 后序遍历

后序遍历(InOrder)的操作过程如下:

  1. 若二叉树为空,则什么也不做;
  2. 若二叉树非空: ①先序遍历左子树; ②先序遍历右子树; ③访问根结点。
    【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第3张图片

三种遍历算法的时间复杂度、空间复杂度都是O(n)。

4. 遍历算数表达式树

【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第4张图片

5. 层次遍历

【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第5张图片【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第6张图片

6. 由遍历序列构造二叉树

若只给出一棵二叉树的 前/中/后/层 序遍历序列中的一种,不能唯一确定一棵二叉树。
前序+中序遍历序列 / 后序+中序遍历序列 / 层序+中序遍历序列 这三种组合能唯一确定一棵二叉树。
前序+中序遍历序列
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第7张图片
后序+中序遍历序列
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第8张图片
层序+中序遍历序列
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第9张图片
小结
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第10张图片

5.3.2 线索二叉树

1. 引言

遍历二叉树是按照一定的规则得到一个线性序列,该序列中的每个结点都有一个前驱和一个后继(除第一个结点和最后一个结点)。
当我们想要得到某结点在遍历中的直接前驱或后继时,我们发现,利用传统的二叉链表实现显得很吃力,其 实现思路如下图1。说明每次想找某一结点的前驱或后缀都要遍历一次。

【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第11张图片

我们知道在含n个结点的二叉树中,用传统的二叉链表存储,共有2n个指针域,有n+1个空指针,那么我们是否可以想办法将这些空指针域利用起来,来实现直接查找结点的前驱或后驱的想法呢?-----可以。
注:引入线索二叉树的目的正是为了加快查找结点前驱和后继的速度,当然了这样也方便遍历。

2. 线索二叉树的存储结构

几个概念:
线索:指向前驱/后 继的指针称为线索。
中序前驱/中序后继:在中序遍历下的结点前驱、结点后继。
先序前驱/先序后继 ;后序前驱/后序后继。

规定:若无左子树,则 lchild指向其前驱结点;若无右子树,则 rchild指向其后继结点。如下图1所示,还需增加两个标志域。
存储结构如下图2。
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第12张图片
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第13张图片

3. 手算画出线索二叉树

有三种线索二叉树,如下图3。
这里仅示例 手算画出中序线索二叉树(如下图4)、其他两个同法。
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第14张图片
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第15张图片

4. 二叉树的线索化(代码)

【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第16张图片

注意:二叉树线索化是将其n+1个空指针都线索化,其遍历的第一个结点的左指针和最后一个结点的右指针都需要线索化,这两个地方是指向NULL,但也是线索化。

(1) 中序线索化

【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第17张图片【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第18张图片

(2) 先序线索化

先序线索化、与中序线索化类似;
但是先序线索化有个要注意的地方,如下图5:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第19张图片
先序线索化代码:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第20张图片【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第21张图片

(3) 后序线索化

【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第22张图片【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第23张图片

(4) 小结

【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第24张图片

5. 线索二叉树找前驱/后继(代码)

(1) 中序线索二叉树找前驱、后继

找后继:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第25张图片【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第26张图片
找前驱:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第27张图片【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第28张图片

(2) 先序线索二叉树找前驱、后继

找后继:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第29张图片
找前驱:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第30张图片
从根结点开始先序遍历查找前驱的代码:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第31张图片
使用三叉链表找先序前驱会遇到的4种情况:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第32张图片

(3) 后序线索二叉树找前驱、后继

找后继:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第33张图片
使用三叉链表找后序后继会遇到的4种情况:
【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第34张图片
找前驱:【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第35张图片

5.3.3 小结

【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第36张图片【数据结构】—— chapter 05 二叉树的遍历和线索二叉树 (part2)_第37张图片

你可能感兴趣的:(数据结构,数据结构,线索树,二叉树的遍历)