树的结构定义和基本术语
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
“访问”的含义可以很广,如:输出结点的信息等。 “遍历”是任何类型数据结构均有的操作,对线性结构而 言,只有一条搜索路径(因为每个结点均只有一个后继),故不 需要另加讨论。而二叉树是非线性结构,每个结点有两个后继, 则存在按什么样的搜索路径遍历的问题。
30
对“二叉树”而言,可以有三条搜索路径: 1.先上后下的按层次遍历; 2.先左(子树)后右(子树)的遍历; 3.先右(子树)后左(子树)的遍历。
void Preorder (BiTree T,void( *visit)(TElemType& e))
{ // 先序遍历二叉树
if (T) {
visit(T->data);
// 访问结点
Preorder(T->lchild, visit); // 遍历左子树
Preorder(T->rchild, visit);// 遍历右子树
false if (p) {Push(s,p); p=p→lchild } //根进栈,遍历左子树 else{
pop(s ,p); if(!visit(p→data)) return ERROR; p=p→rchild;} } while return OK } //算法6.2:根、右子均进栈,用双重循环
根结点 B
A C
D 左子树
右子树
E F
G
H
K
11
二叉树的五种基本形态:
空树
只含根结点
N
右子树为空树 N
左子树为空树 N
左右子树均 不为空树
N
L
R
L
R
12
6.2.2 二叉树的特性
性质 1
在二叉树的第 i 层上至多有2i-1 个结点。
(i≥1)
用归纳法证明: i = 1 层时,只有一个根结点,
归纳基:
32
先(根)序遍历递归算法(中文): 若二叉树为空树,则空操作;否则, (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。
33
中(根)序递归算法(中文) : 若二叉树为空树,则空操作;否则, (1)中序遍历左子树; (2)访问根结点; (3)中序遍历右子树。
34
后(根)序遍历递归算法(中文) : 若二叉树为空树,则空操作;否则, (1)后序遍历左子树; (2)后序遍历右子树; (3)访问根结点。
故k= log2n +1
17
性质5:完全二叉树中,已知点i可推知其父点,子点位置。 有n个结点的完全二叉树(即其深度为log2n +1),
是如上述有序表示的,则对任一结点i,1<=i<=n,则有: (1)如果i=1,则i是根无双亲; 如果i>1,i的双亲是 PARENT(i)是 i/2 。 (2)如果2i<=n, 则i的左子LCHILD(i)是结点2i, 否则i无左子。 (3)如果2i+1<=n,则i的右子RCHILD(i)是结点2i+1, 否则,则i无右子。
树的结构定义和基本术语
6.1 树的定义和基本术语
定义: 树(Tree)是n(n>=0)个结点的有限集。在任意一棵非空树
中: (1) 存在唯一的称为根的结点root, (2) 当n>1时,其余结点可分为m (m>0)个互不相交的有
限集T1, T2, …, Tm, 其中每一个集合本身又是一棵符合本 定义的树,并且称为根的子树。
16
性质4:完全二叉树具有n个结点的完全二叉树的深度为 log2n +1
证:(1)设树深度为k,根据性质2,n<=2k-1 (2)由定义:n大于深度为k-1的满二叉树的结点数2k-1-1 因此 2k-1-1<n<=2k-1 即 2k-1<=n<2k (不等式原理) k-1<=log2n<k k是整数 k-1= log2n 成立 (取等号式子)
2i-1 = 20 = 1;
归纳假设: 假设对i-1层,命题成立;即有2i-2个结点 归纳证明: 二叉树上每个结点至多有两棵子树,
则第 i 层的结点数 = 2i-2 2 = 2i-1 。
13
性质 2 : 深度为 k 的二叉树上至多含 2k-1 个(k≥1) 证明:
基于性质1,深度为 k 的二叉树上的结点数至多为
6
F
root
A
B
C
D
E
F G H IJ
K
L
M
任何一棵非空树是一个二元组 Tree = (root,F)
其中:root 被称为根结点, F 被称为子树森林
7
有向树: (1) 有确定的根; (2) 树根和子树根之间为有向关系。
有序树: 子树之间存在确定的次序关系。
无序树: 子树之间不存在确定的次序关系。
一、双亲表示法 二、孩子链表表示法 三、孩子-兄弟表示法(树的二叉链表)
44
一、双亲表示法:
A BC D
EF G
data parent
0 A -1 r=0 1 B 0 n=6 2C 0 3D 0 4E 2 5F 2 6G 5
45
二、孩子链表表示法:
1、多重链表表示法:每个结点有多个指针域,其中每个 指针指向一棵子树根结点。有两种表示方式; a) 非固定大小结点结构 b) 链表中结点同构,链表中域的数目为树的度。
D E
F
25
C 语言的类型描述如下:
typedef struct BiTNode { // 结点结构
TElemType
data;
struct BiTNode *lchild, *rchild;
// 左右孩子指针
} BiTNode, *BiTree;
结点结构:
lchild data rchild
26
二叉树(binary tree)是另一种树型结构,它的特点是 每个结点至多只有二棵子树(即二叉树中不存在度大于2的结 点),并且,二叉树的子树有左右之分,其次序不能任意颠 倒。
10
定义: 二叉树或为空树;或是由一个根结点加上两棵分别称为 左子树和右子树的、互不交的二叉树组成。这也是一个递归定 义。二叉树不是树的特殊情况,它们是两个独立的概念。
2.三叉链表
root
结点结构:
parent lchild data rchild
A B
C
D
E
F
27
C 语言的类型描述如下:
typedef struct TriTNode { // 结点结构
TElemType
data;
struct TriTNode *lchild, *rchild;
// 左右孩子指针
20+21+ +2k-1 = 2k-1
14
性质 3 : 对任何一棵二叉树,若它含有n0 个叶子结点、n2 个度
为 2 的结点,则必存在关系式:n0 = n2+1
证明:
设 二叉树上结点总数
n = n0 + n1 + n2
又 二叉树上分支总数
b = n1+2n2
由此, n0 = n2 + 1
35
例如:
先序遍历如图所示之二叉树,按访问结点的先后次序将
结点排列起来,其先序序列为: -
-+a*b-cd/ef 按中序遍历,其中序序列为:
a+b*c-d-e/f 按后序遍历,其后序序列为:
abcd-*+ef/-
+ a*
/ ef
b-
分别称之为前缀、中缀、后缀表示
cd
36
三、先序遍历递归算法的描述
}
}
37
先序遍历递归算法的描述(补充)
status PreOrderT(BiTree T) { if (T != NULL) { printf (“%d”,T -> data); PreOrderT (T-> Lchild); PreOrderT (T-> rchild);} }
38
四、中序遍历递归算法的描述
31
二、遍历方法
假如以L、D、R分别表示遍历左子树、遍历根结点和 遍历右子树,遍历整个二叉树则有DLR、LDR、LRD、DRL、 RDL、RLD六种遍历方案。
对左右子树若规定先左后右,则有: DLR——先(根)序遍历, LDR——中(根)序遍历, LRD——后(根)序遍历。
对左右子树若规定先右后左,则有: DRL——逆先(根)序遍历, RDL——逆中(根)序遍历, RLD——逆后(根)序遍历。
status InOrederT (BiTree T){ if (T != NULL){ InOrederT (T -> Lchild); printf (“%d”,T-> data); InOrderT ( T -> rchild);}
}
以图6.9为例分析执行过程。
39
五、中序遍历非递归算法6.3 说明:只根点进栈,左右子为空时不进栈 P131 Status InOrder T (BiTree T,Status(*Visit)(TelemType e)){ InitStack (S); p=T; //P扫描 While (p‖StackEmpty(S)) { //P46,S空则返回True,S非空返回
A B CDE F GHI J K L
22
0
一般二叉树
A
1
B
4
C
2
D
6
E
13
F
0 1 2 3 4 5 6 7 8 9 10 11 12 13
AB D C E
F
23
二、二叉树的链式存储表示 1. 二叉链表 2.三叉链表
24
1. 二叉链表 root
A B
C
结点结构: lchild data rchild
20
二叉树顺序存储描述
#define MAX_TREE_SIZE 100 // 二叉树的最大结点数
typedef TElemType SqBiTree[MAX_TREE_SIZE]; // 0号单元存储根结点
SqBiTree bt;
21
a
完全二叉树
b
c
d
e
f
g
h i j kl
1 2 3 4 5 6 7 8 9 10 11 12
8
对比树型结构和线性结构的结构特点
线性结构
树型结构
关系: (1 : 1)
关系: (1 : M)
第一个数据元素 (无前驱)
根结点 (无前驱)
最后一个数据元素 (无后继)
多个叶子结点 (无后继)
其它数据元素 (一个前驱、
一个后继)
其它数据元素 (一个前驱、
多个后继)
9
6.2 二叉树
6.2.1 二叉树的概念来自D叶子结点: 度为零的结点 分支结点: 度大于零的结点
H
I
J
M
5
路径:
由从根到该结点所经分支 和结点构成
孩子结点、双亲结点、 兄弟结点、堂兄弟 祖先结点、子孙结点
A
B
C
D
E
F G H IJ
K
L
M
结点的层次: 假设根结点的层次为1,第l 层的结点的子树根结点 的层次为l+1
树的深度:树中叶子结点所在的最大层次 森林:是m(m≥0)棵互不相交的树的集合
struct TriTNode *parent; //双亲指针
} TriTNode, *TriTree;
结点结构:
parent lchild
data rchild
28
6.3 遍历二叉树
6.3.1 遍历二叉树
一、问题的提出 二、遍历算法 三、建立二叉树
29
一、问题的提出
顺着某一条搜索路径巡访二叉树中的结点,使得每个结点 均被访问一次,而且仅被访问一次,此处理过程称为遍历。
3
例如:
(a)
(b)
A( B (E (K, L) , F), C ( G ), D ( H ( M ) , I , J ) )
树根
T1
T2
T3
•上面是图的广义表表示形式 •图的嵌套形式表示和凹入表示法见图6.2
4
基本术语
结点:
数据元素+若干指向子树的链接
结点的度: 分支的个数
树的度: 树中所有结点的度的最大值
40
六、先序建立二叉树的算法
Status CreateBiT(BiTree&T) { scanf(&ch); If(ch==”) T=NULL; else{ T =(BiTNode *) malloc (sizeof(BiTNode)); T→data=ch; CreateBiT(T→lchild); CreateBiT(T→rchild);} return OK
而 b = n-1 = n0 + n1 + n2 – 1
(1) (2)
15
两类特殊的二叉树:
1
满二叉树:指的是深度为k且含
2
有2k-1个结点的二叉树。
4
5
3
6
7
8 9 10 11 12 13 14 15
完全二叉树:树中所含的 n
个结点和满二叉树中编号为
a
1 至 n 的结点一一对应。
b
c
d
e
f
g
hi j
18
6.2.3 二叉树的存储结构
一、 二叉树的顺序存储表示 二、二叉树的链式存储表示
19
一、 二叉树的顺序存储表示
用一组地址连续的存储单元存储完全二叉树的数据元 素。即将完全二叉树中编号为i的结点的数据元素存放在 分量bt[i-1]中。但这种顺序存储结构仅适合于满二叉树 和完全二叉树,而一般二叉树按这种形式存储将造成存贮 浪费。
}
以字符串的形式 按先序序列建立一棵二叉树
例如:
空树 以空白字符“ ”表示
只含一个根结点的二叉树 A 以字符串“A
”表示
A B
C
以下列字符串表示 D A(B( ,C( , )),D( , ))
42
建立过程举例如下:
AB C D
T
A
^B
^D^
^C^
43
6.4 树和森林
6.4.1 树的三种存储结构
30
对“二叉树”而言,可以有三条搜索路径: 1.先上后下的按层次遍历; 2.先左(子树)后右(子树)的遍历; 3.先右(子树)后左(子树)的遍历。
void Preorder (BiTree T,void( *visit)(TElemType& e))
{ // 先序遍历二叉树
if (T) {
visit(T->data);
// 访问结点
Preorder(T->lchild, visit); // 遍历左子树
Preorder(T->rchild, visit);// 遍历右子树
false if (p) {Push(s,p); p=p→lchild } //根进栈,遍历左子树 else{
pop(s ,p); if(!visit(p→data)) return ERROR; p=p→rchild;} } while return OK } //算法6.2:根、右子均进栈,用双重循环
根结点 B
A C
D 左子树
右子树
E F
G
H
K
11
二叉树的五种基本形态:
空树
只含根结点
N
右子树为空树 N
左子树为空树 N
左右子树均 不为空树
N
L
R
L
R
12
6.2.2 二叉树的特性
性质 1
在二叉树的第 i 层上至多有2i-1 个结点。
(i≥1)
用归纳法证明: i = 1 层时,只有一个根结点,
归纳基:
32
先(根)序遍历递归算法(中文): 若二叉树为空树,则空操作;否则, (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。
33
中(根)序递归算法(中文) : 若二叉树为空树,则空操作;否则, (1)中序遍历左子树; (2)访问根结点; (3)中序遍历右子树。
34
后(根)序遍历递归算法(中文) : 若二叉树为空树,则空操作;否则, (1)后序遍历左子树; (2)后序遍历右子树; (3)访问根结点。
故k= log2n +1
17
性质5:完全二叉树中,已知点i可推知其父点,子点位置。 有n个结点的完全二叉树(即其深度为log2n +1),
是如上述有序表示的,则对任一结点i,1<=i<=n,则有: (1)如果i=1,则i是根无双亲; 如果i>1,i的双亲是 PARENT(i)是 i/2 。 (2)如果2i<=n, 则i的左子LCHILD(i)是结点2i, 否则i无左子。 (3)如果2i+1<=n,则i的右子RCHILD(i)是结点2i+1, 否则,则i无右子。
树的结构定义和基本术语
6.1 树的定义和基本术语
定义: 树(Tree)是n(n>=0)个结点的有限集。在任意一棵非空树
中: (1) 存在唯一的称为根的结点root, (2) 当n>1时,其余结点可分为m (m>0)个互不相交的有
限集T1, T2, …, Tm, 其中每一个集合本身又是一棵符合本 定义的树,并且称为根的子树。
16
性质4:完全二叉树具有n个结点的完全二叉树的深度为 log2n +1
证:(1)设树深度为k,根据性质2,n<=2k-1 (2)由定义:n大于深度为k-1的满二叉树的结点数2k-1-1 因此 2k-1-1<n<=2k-1 即 2k-1<=n<2k (不等式原理) k-1<=log2n<k k是整数 k-1= log2n 成立 (取等号式子)
2i-1 = 20 = 1;
归纳假设: 假设对i-1层,命题成立;即有2i-2个结点 归纳证明: 二叉树上每个结点至多有两棵子树,
则第 i 层的结点数 = 2i-2 2 = 2i-1 。
13
性质 2 : 深度为 k 的二叉树上至多含 2k-1 个(k≥1) 证明:
基于性质1,深度为 k 的二叉树上的结点数至多为
6
F
root
A
B
C
D
E
F G H IJ
K
L
M
任何一棵非空树是一个二元组 Tree = (root,F)
其中:root 被称为根结点, F 被称为子树森林
7
有向树: (1) 有确定的根; (2) 树根和子树根之间为有向关系。
有序树: 子树之间存在确定的次序关系。
无序树: 子树之间不存在确定的次序关系。
一、双亲表示法 二、孩子链表表示法 三、孩子-兄弟表示法(树的二叉链表)
44
一、双亲表示法:
A BC D
EF G
data parent
0 A -1 r=0 1 B 0 n=6 2C 0 3D 0 4E 2 5F 2 6G 5
45
二、孩子链表表示法:
1、多重链表表示法:每个结点有多个指针域,其中每个 指针指向一棵子树根结点。有两种表示方式; a) 非固定大小结点结构 b) 链表中结点同构,链表中域的数目为树的度。
D E
F
25
C 语言的类型描述如下:
typedef struct BiTNode { // 结点结构
TElemType
data;
struct BiTNode *lchild, *rchild;
// 左右孩子指针
} BiTNode, *BiTree;
结点结构:
lchild data rchild
26
二叉树(binary tree)是另一种树型结构,它的特点是 每个结点至多只有二棵子树(即二叉树中不存在度大于2的结 点),并且,二叉树的子树有左右之分,其次序不能任意颠 倒。
10
定义: 二叉树或为空树;或是由一个根结点加上两棵分别称为 左子树和右子树的、互不交的二叉树组成。这也是一个递归定 义。二叉树不是树的特殊情况,它们是两个独立的概念。
2.三叉链表
root
结点结构:
parent lchild data rchild
A B
C
D
E
F
27
C 语言的类型描述如下:
typedef struct TriTNode { // 结点结构
TElemType
data;
struct TriTNode *lchild, *rchild;
// 左右孩子指针
20+21+ +2k-1 = 2k-1
14
性质 3 : 对任何一棵二叉树,若它含有n0 个叶子结点、n2 个度
为 2 的结点,则必存在关系式:n0 = n2+1
证明:
设 二叉树上结点总数
n = n0 + n1 + n2
又 二叉树上分支总数
b = n1+2n2
由此, n0 = n2 + 1
35
例如:
先序遍历如图所示之二叉树,按访问结点的先后次序将
结点排列起来,其先序序列为: -
-+a*b-cd/ef 按中序遍历,其中序序列为:
a+b*c-d-e/f 按后序遍历,其后序序列为:
abcd-*+ef/-
+ a*
/ ef
b-
分别称之为前缀、中缀、后缀表示
cd
36
三、先序遍历递归算法的描述
}
}
37
先序遍历递归算法的描述(补充)
status PreOrderT(BiTree T) { if (T != NULL) { printf (“%d”,T -> data); PreOrderT (T-> Lchild); PreOrderT (T-> rchild);} }
38
四、中序遍历递归算法的描述
31
二、遍历方法
假如以L、D、R分别表示遍历左子树、遍历根结点和 遍历右子树,遍历整个二叉树则有DLR、LDR、LRD、DRL、 RDL、RLD六种遍历方案。
对左右子树若规定先左后右,则有: DLR——先(根)序遍历, LDR——中(根)序遍历, LRD——后(根)序遍历。
对左右子树若规定先右后左,则有: DRL——逆先(根)序遍历, RDL——逆中(根)序遍历, RLD——逆后(根)序遍历。
status InOrederT (BiTree T){ if (T != NULL){ InOrederT (T -> Lchild); printf (“%d”,T-> data); InOrderT ( T -> rchild);}
}
以图6.9为例分析执行过程。
39
五、中序遍历非递归算法6.3 说明:只根点进栈,左右子为空时不进栈 P131 Status InOrder T (BiTree T,Status(*Visit)(TelemType e)){ InitStack (S); p=T; //P扫描 While (p‖StackEmpty(S)) { //P46,S空则返回True,S非空返回
A B CDE F GHI J K L
22
0
一般二叉树
A
1
B
4
C
2
D
6
E
13
F
0 1 2 3 4 5 6 7 8 9 10 11 12 13
AB D C E
F
23
二、二叉树的链式存储表示 1. 二叉链表 2.三叉链表
24
1. 二叉链表 root
A B
C
结点结构: lchild data rchild
20
二叉树顺序存储描述
#define MAX_TREE_SIZE 100 // 二叉树的最大结点数
typedef TElemType SqBiTree[MAX_TREE_SIZE]; // 0号单元存储根结点
SqBiTree bt;
21
a
完全二叉树
b
c
d
e
f
g
h i j kl
1 2 3 4 5 6 7 8 9 10 11 12
8
对比树型结构和线性结构的结构特点
线性结构
树型结构
关系: (1 : 1)
关系: (1 : M)
第一个数据元素 (无前驱)
根结点 (无前驱)
最后一个数据元素 (无后继)
多个叶子结点 (无后继)
其它数据元素 (一个前驱、
一个后继)
其它数据元素 (一个前驱、
多个后继)
9
6.2 二叉树
6.2.1 二叉树的概念来自D叶子结点: 度为零的结点 分支结点: 度大于零的结点
H
I
J
M
5
路径:
由从根到该结点所经分支 和结点构成
孩子结点、双亲结点、 兄弟结点、堂兄弟 祖先结点、子孙结点
A
B
C
D
E
F G H IJ
K
L
M
结点的层次: 假设根结点的层次为1,第l 层的结点的子树根结点 的层次为l+1
树的深度:树中叶子结点所在的最大层次 森林:是m(m≥0)棵互不相交的树的集合
struct TriTNode *parent; //双亲指针
} TriTNode, *TriTree;
结点结构:
parent lchild
data rchild
28
6.3 遍历二叉树
6.3.1 遍历二叉树
一、问题的提出 二、遍历算法 三、建立二叉树
29
一、问题的提出
顺着某一条搜索路径巡访二叉树中的结点,使得每个结点 均被访问一次,而且仅被访问一次,此处理过程称为遍历。
3
例如:
(a)
(b)
A( B (E (K, L) , F), C ( G ), D ( H ( M ) , I , J ) )
树根
T1
T2
T3
•上面是图的广义表表示形式 •图的嵌套形式表示和凹入表示法见图6.2
4
基本术语
结点:
数据元素+若干指向子树的链接
结点的度: 分支的个数
树的度: 树中所有结点的度的最大值
40
六、先序建立二叉树的算法
Status CreateBiT(BiTree&T) { scanf(&ch); If(ch==”) T=NULL; else{ T =(BiTNode *) malloc (sizeof(BiTNode)); T→data=ch; CreateBiT(T→lchild); CreateBiT(T→rchild);} return OK
而 b = n-1 = n0 + n1 + n2 – 1
(1) (2)
15
两类特殊的二叉树:
1
满二叉树:指的是深度为k且含
2
有2k-1个结点的二叉树。
4
5
3
6
7
8 9 10 11 12 13 14 15
完全二叉树:树中所含的 n
个结点和满二叉树中编号为
a
1 至 n 的结点一一对应。
b
c
d
e
f
g
hi j
18
6.2.3 二叉树的存储结构
一、 二叉树的顺序存储表示 二、二叉树的链式存储表示
19
一、 二叉树的顺序存储表示
用一组地址连续的存储单元存储完全二叉树的数据元 素。即将完全二叉树中编号为i的结点的数据元素存放在 分量bt[i-1]中。但这种顺序存储结构仅适合于满二叉树 和完全二叉树,而一般二叉树按这种形式存储将造成存贮 浪费。
}
以字符串的形式 按先序序列建立一棵二叉树
例如:
空树 以空白字符“ ”表示
只含一个根结点的二叉树 A 以字符串“A
”表示
A B
C
以下列字符串表示 D A(B( ,C( , )),D( , ))
42
建立过程举例如下:
AB C D
T
A
^B
^D^
^C^
43
6.4 树和森林
6.4.1 树的三种存储结构