二叉树的存储与遍历
{ if ( T )
{ //如果二叉树不为空
Inorder ( T -> lchild ) ; //中序遍历左子树
printf( T -> data) ;
//输出根结点
Inorder ( T -> rchild ) ; //中序遍历右子树
// 左右孩子指针
} BiTNode, *BiTree;
2)三叉链表
例2:对例1
root
lchild
结点结构 data parent rchild
A
B
D
C
E
F
类型定义
typedef struct TriTNode { // 结点结构 TElemType data; struct TriTNode *lchild, *rchild;
Preorder ( T -> rchild ) ; //先序遍历右子树
}
}
2)中序遍历算法
若二叉树为空,则空操作;
否则,
中序遍历左子树; 访问根结点;
D
L
RБайду номын сангаас
中序遍历右子树。
例3: 中序遍历
L
D
R
A
A
B
C
LD R
L DR
□
D
□
□
□
□
B
C
L DR
中序遍历序列:B D A C
D
递归算法描述
void Inorder ( BiTree T )
// 左右孩子指针
struct TriTNode *parent; //双亲指针 } TriTNode, *TriTree;
例3: 链式存储结构示例
A
B
C
DE A
F A∧
B
∧C
B
∧C
∧ D ∧ ∧ E ∧ ∧ F ∧ ∧ D ∧ ∧∧ E ∧∧ ∧∧ F ∧∧
二叉链表
三叉链表
注意:对于一棵二叉树,若采用二叉链表
例1: 完全二叉树存储
1
2
3
4
5
6
7
8
9 10
1 2 3 4 5 6 7 8 9 10
例2: 非完全二叉树存储
1
A
2
B
5C
3
D
7
E
14
F
1 2 3 4 5 6 7 8 9 10 11 12 13 14
AB D 0 C 0 E 0 0 0 0 0 0F
注意:1)对于一棵二叉树,若采用顺序存储
时,对完全二叉树,比较方便;对非完全二 叉树,将会浪费大量存储单元。
存储时,当二叉树为非完全二叉树时,比较 方便,若为完全二叉树时,将会占用较多存 储单元(存放地址的指针)。
若一棵二叉树有n个结点,采用二叉链表作 存储结构时,共有2n个指针域,其中只有n1个?指针指向左右孩子,其余n+1个指? 针为 空。
在二叉链表结构中的操作
查询元素? 查询元素的后继? 查询元素的前驱?
【重点难点】
遍历二叉树的递归算法及其应用 ,二叉树线索化
【教学内容】
§6.2.3 二叉树的存储结构 §6.3.1 遍历二叉树 §6.3.2 线索二叉树
【内容回顾】
6.1 树的定义和基本术语 6.2 二叉树
-6.2.1 二叉树的定义 -6.2.2 二叉树的性质
【课题导入】
回顾线性表的存储方法? 顺序存储 链式存储
§6.2.3 二叉树的存储结构
1. 顺序存储结构
约定用一组地址连续的存储单元依次自上而 下,自左至右存储完全二叉树上的结点元素。
#define MAX_TREE_SIZE 100 // 二叉树的最大结点数 typedef TElemType SqBiTree[MAX_TREE_SIZE];
// 0号单元存储根结点 SqBiTree bt;
根据二叉树的结构,分为三部分:
L 左子树
D 根结点 R 右子树
遍历二叉树的方法:
D
L
R
先序遍历 DLR 中序遍历 LDR 后序遍历 LRD
由于其中的左右子树也是二叉树,属于递归
结构,所以常常借助递归算法实现。
1)先序遍历算法
若二叉树为空,则空操作;
否则,
访问根结点; 先序遍历左子树;
对“二叉树”而言,可以有两 条搜索路径:
➢ 先上后下的按层次遍历; ➢ 先左(子树)后右(子树)
的遍历;
2、先上后下的按层次遍历
从第一层开始,同一层从左到右。
例1:如右图 按层次遍历序列为: ABFCGDEH
A B
C DE
F G
H
特点:先被遍历的结点的孩子先于后遍历 的结点的孩子遍历。
3、先左后右的遍历算法
2)最坏的非完全二叉树是只有右分支,设 高度为K,则需占用2K?-1个存储单元,而实 际只有k个元素,实际只需k个存储单元。
因此,对于非完全二叉树,不宜采用顺 序存储结构。
顺序结构存储二叉树的优点
1)存储时,元素的位置(下标+1)对应 其在完全二叉树中的序号。
2)可快速方便地访问元素的双亲和左 右孩子。
【学习目标】
1.熟练掌握二叉链表存储结构; 2.熟练掌握遍历二叉树的递归算法,并能够实现二叉树的其它 操作; 3.了解按层次遍历二叉树的算法,能够熟练写出给定二叉树的 各种遍历序列,会根据给定的遍历序列画出二叉树。 4. 理解二叉树线索化的实质是建立结点与其在相应序列中的前 驱或后继之间的直接联系。了解二叉树的线索化过程以及在中 序线索化树上找给定结点的前驱和后继的方法。能够熟练地画 出给定二叉树的各种线索。
2、链式存储表示
1)二叉链表 2)三叉链表
1) 二叉链表
例1:
A
root
结点结构 lchild data rchild
A
B
D
C
E
F
B C
D E
F
类型定义
typedef struct BiTNode { // 结点结构 TElemType data; struct BiTNode *lchild, *rchild;
D
L
R
先序遍历右子树。
例2: 先序遍历
A
B
C
D
L
R
A D LR
D LR
□
D
□
□
B
□
□
先序遍历序列:A B D C
C D LR
D
递归算法描述
void Preorder ( BiTree T )
{ if ( T )
{ //如果二叉树不为空
printf( T -> data) ;
//输出根结点
Preorder ( T -> lchild ) ; //先序遍历左子树
这种存储结构的特点是: 寻找孩子结点容易,双亲比较困难。
§6.3.1 遍历二叉树
1、导入 2、先上后下的按层次遍历 3、先左后右的遍历算法 4、遍历二叉树的应用
1、导入
问题:怎样在二叉树中查找具有某种特征的结点? 怎样对二叉树中全部结点逐一进行某种处理?
遍历二叉树:即如何按照某条搜索路径巡访二叉树 中每个结点,使得每个结点均被访问一次,而且仅 被访问一次。 “访问”的含义可以很广,如:输出结点的信息, 对结点进行统一的操作等。