第六章 树和二叉树 2
第6章 树和二叉树
二叉树的存储结构
1. 二叉树的顺序存储表示
DeleteChild( T, p, LR ); 初始条件:二叉树 T 存在。 操作结果:根据LR的值,删除结点p的子树。
✓ 加工型操作(续)
Assign( T, &e, value ) 初始条件:二叉树 T 存在。 操作结果:用 value 给当前结点 e 赋值。
ClearBiTree( &T ) 初始条件:二叉树 T 存在。 操作结果:清空二叉树中的所有结点。
Value( T, cur_e ) 初始条件:树 T 存在。 操作结果:用 cur_e 返回当前结点的元素值。
Parent( T, cur_e ) 初始条件:树 T 存在。 操作结果:用 cur_e 返回当前结点双亲的元素值。
✓ 引用型操作(续)
LeftSibling( T, cur_e ) 初始条件:树 T 存在。 操作结果:用 cur_e 返回当前结点左兄弟的元素值。
证明:
设二叉树上结点总数 n = n0 + n1 + n2,二叉树上分支总数 (总度数) b = n1+2n2,而 b = n-1 = n0 + n1 + n2 – 1,由此, n0 = n2 + 1。
除根结点外,每个结 点指向双亲结点的分
支只有一条。
两类特殊的二叉树:
满二叉树(Full Binary Tree) :指的是深度为 k 且含有 2k-1 个结点的二 叉树。
06树与二叉树详解2PPT课件
12.11.2020
2
本讲主要介绍以下几个方面的内容: • 树的定义及基本概念; • 树、森林与二叉树之间的相互转换; • 树的各种存储结构; • 树、森林的遍历。
12.11.2020
3
6.1 树 的 概 述
6.1.1 树的定义及特性
所谓“树(Tree)”是指由n(n≥0) 个结点构成的有限数据元素的集合T。当n=0 时,称其为“空树”。当n≠0时,树中诸结 点应该满足下面的两个条件:
只有无右子树的二叉树,才能通过转换 成为一棵树。具体步骤如下:
(1)找到二叉树中某结点的右孩子及右 孩子的右孩子……,在它们与该结点的双亲 结点之间添加连线;
树中度大于0的结点称为分支结点,或 非终端结点。
12.11.2020
12
• 路径 从树中一个结点到另一个结点之间的分
支,称为这两个结点间的路径。 • 路径长度
一条路径上的分支数,称为该路径的长 度。
12.11.2020
13
2.有关结点间关系的术语
• 根结点 所谓“根”结点,即是指树中没有直接
前驱的那个结点。一棵树,只能有一个根结 点。 • 孩子结点
棵树的度。 • 树的深度
一棵树中各结点的深度的最大值,称为 该树的深度。树的深度有时也称为树的高度。
12.11.2020
17
• 有序树与无序树 如果限定树中各结点的子树从左至右的
排列具有一定顺序,不得互换,那么就称该 树是有序的,否则称为是无序树。 • 森林
n(n≥0)棵互不相交的树的集合,称 为森林。
12.11.2020
22
例:将图6-6(a)所示的树,转换成它所 对应的二叉树。
12.11.2020
23
第6章 树和二叉树2
2. 从森林F中选取根权值最小的两棵树,分别作为左子
树和右子树,再新添一个结点做为根,合并成一棵新的 二叉树,新二叉树根的权值等于左、右子树根权值之和。 3. 重复2,直到F中只剩下一棵树为止,这棵树就是所求 的Huffman树。
哈夫曼树及其应用 • 哈夫曼树的构造
a
b
c
d
e
f
6
1
5
4
2
4
3
b e
WPL
i 1
wi li
n
n—树叶个数
哈夫曼树:由权值为{ w1,w2,...,wn)的n片叶子构成的所
有二叉树中,WPL值最小的二叉树。 哈夫曼树又被称为最优二叉树
哈夫曼树及其应用 • 哈夫曼树的定义
1. 哈夫曼树不一定是最矮的树 A B C D 7哈夫曼树形态可能不唯一 5 2 4 2. A B C D
先序序列:ABEJFCDGHKI 中序序列:JEFBCGKHIDA 后序序列:JFEKIHGDCBA
树和森林 • 树和森林的遍历
先序遍历树,等价于先序遍历由这棵树转换 而成的二叉树; 后序遍历树,等价于中序遍历由这棵树转换 而成的二叉树;
树和森林 • 树和森林的遍历
3. 先序遍历森林: 若森林不空,则
E
F G I
H J L K
E F
H
F
H
B
D
C
G
I
JG
L
K
I
J
L
K
树、森林与二叉树的关系 • 森林转换成二叉树
A B D C
E
F G A B E C G I J L I
H J L K
D
F H
K
云大《数据结构》课程教学课件-第6章 树和二叉树(147P)_OK
^d ^ ^ e ^ 三叉链表
3)二叉链表是二叉树最常用的存储结构。还有其它链接方 法,采用何种方法,主要取决于所要实施的各种运算频度。
例:若经常要在二叉树中寻找某结点的双亲时,可在每个结 点上再加一个指向其双亲的指针域parent,称为三叉链表。
lchild data parent rchild
2021/8/16
2021/8/16
9
6.2 二 叉 树
6.2.1 二叉树的概念
一、二叉树的定义: 二叉树(Binary Tree)是n(n>=0)个结点的有限集,它或者是 空集(n=0)或者由一个根结点和两棵互不相交的,分别称 为根的左子树和右子树的二叉树组成。 可以看出,二叉树的定义和树的定义一样,均为递归定 义。
A
集合3
集合1
BCD
EF
G
集合2
2021/8/16
3
2、树的表示方法 1)树形图法
A
BCD
EF
G
2)嵌套集合法
3)广义表形式 ( A(B, C(E,F), D(G) )
4)凹入表示法
2021/8/16
A B
D
CG
EF
A B C E DF G
4
3、 树结构的基本术语
1)结点的度(Degree):为该结点的子树的个数。 2)树的度:为该树中结点的最大度数。
7)路径(Path):若树中存在一个结点序列k1,k2,…,kj,使得ki是 ki+1的双亲(1<=i<j),则称该结点序列是从ki到kj一条路径 (Path)
路径长度:路径的长度为j-1,其为该路径所经过的边的数 目。
A
BCD
EF
G
第6章树和二叉树(2)培训讲学
第6章树和二叉树(2)第六章树和二叉树一、选择题1.算术表达式a+b*(c+d/e)转为后缀表达式后为()A.ab+cde/* B.abcde/+*+ C.abcde/*++ D.abcde*/++2. 设森林F对应的二叉树为B,它有m个结点,B的根为p,p的右子树结点个数为n,森林F中第一棵树的结点个数是()A.m-n B.m-n-1 C.n+1 D.条件不足,无法确定3.若度为m的哈夫曼树中,其叶结点个数为n,则非叶结点的个数为()。
A.n-1 B.⎣n/m⎦-1 C.⎡(n-1)/(m-1)⎤ D.⎡n/(m-1)⎤-1E.⎡(n+1)/(m+1)⎤-14.深度为h的满m叉树的第k层有()个结点。
(1=<k=<h)A.m k-1 B.m k-1 C.m h-1 D.m h-15. 若X是二叉中序线索树中一个有左孩子的结点,且X不为根,则x的前驱为( )A.X的双亲B.X的右子树中最左的结点C.X的左子树中最右结点D.X的左子树中最右叶结点6. 引入二叉线索树的目的是()A.加快查找结点的前驱或后继的速度 B.为了能在二叉树中方便的进行插入与删除C.为了能方便的找到双亲 D.使二叉树的遍历结果唯一7.由3 个结点可以构造出多少种不同的二叉树?()A.2 B.3 C.4 D.58.下述编码中哪一个不是前缀码()。
A.(00,01,10,11) B.(0,1,00,11) C.(0,10,110,111)D.(1,01,000,001)二、判断题1. 给定一棵树,可以找到唯一的一棵二叉树与之对应。
2.将一棵树转成二叉树,根结点没有左子树;3. 在中序线索二叉树中,每一非空的线索均指向其祖先结点。
4. 一棵哈夫曼树的带权路径长度等于其中所有分支结点的权值之和。
5.当一棵具有n个叶子结点的二叉树的WPL值为最小时,称其树为Huffman树,且其二叉树的形状必是唯一的。
三、填空题1.一棵树T中,包括一个度为1的结点,两个度为2的结点,三个度为3的结点,四个度为4的结点和若干叶子结点,则T的叶结点数为___ ___。
第六章-树和二叉树
之
树 和 二 叉 树 13
1 2 3 A B C
4 5 6 7 0 D E F
8 0
9 10 0 G
¾ 二叉树顺序存储的算法描述
数 据 结 构
¾ 初始化二叉树
之
树 和 二 叉 树 14
#define Max_Size 100 typedef int TElemType; typedef TElemType SqBT[Max_Size+1]; void InitBT(SqBT bt){//设置空树 int i; for(i=1;i<=Max_Size;i++) bt[i]=0; }
数 据 结 构
之
树 和 二 叉 树 19
¾ 后序遍历顺序二叉树算法 void PostBT(SqBT bt,int i){ if(i>Max_Size||!bt[i]) return; PostBT(bt,2*i); PostBT(bt,2*i+1); printf("%3d ",bt[i]); }
数 据 结 构
之
树 和 二 叉 树 4
5. 孩子结点、双亲结点、兄弟结点、堂兄弟 结点、祖先结点、子孙结点…… 6. 结点的层次从根开始,根为第一层,根的 孩子为第二层;若某结点在第L层,则其 子树的根就在第L+1层。 7. 树的深度或高度:树中结点的最大层次。 8. 有序树:如果将树中结点的各子树看成是 从左至右有次序的;反之,则是无序树。 9. 森林:是m棵互不相交的树的集合。
数 据 结 构
之
树 和 二 叉 树 25
¾ 打印一维数组 void printSq(SqBT bt){ int i; printf("\nSeqArray:"); for(i=1;i<=Max_Size;i++) printf("%3d ",bt[i]); }
第6章(树和二叉树)
^ ^
^
C
^ ^
E
D
G
24/106
在n个结点的 三叉链表 中,有n+2个 空指针域
^ ^
G
F
^
^
用链表表示的二叉树中也会存在许多空链域。例如在含有n个 结点的二叉链表中,共有2n个链域,实际用n-1链域(仅有n-1 个分支),还有n+1个空链域。 可以利用这些空链域存储其它有用信息,从而得到另一种链式 存储结构——线索链表。
B=n1+2n2
因此,N=B+1=n1+2n2+1
(6-2)
由式(6-1)和(6-2)得到:
n0+n1+n2=n1+2n2+1
可得 n0=n2+1
性质3: 对任何一棵二叉树T,如果其终端结点数为n0,度为2的 结点数为n2,则n0=n2+1。
11/106
下面介绍两种特殊形态的二叉树: 满二叉树和完全二叉树。
假设此二叉树的深度为k,则根据性质2及完全二叉树的定义得:
2k-1-1<n≤2k-1 或 2k-1≤n<2k
取对数得到: k-1≤ log2n < k ,又因为k是整数,所以有: k= log2n +1
14/106
性质5: 如果对一棵有n个结点的完全二叉树的结点按层序 编号(从第1层到第log2n +1层,每层从左到右),则对任 一结点i(1≤i≤n),有: (1)如果i=1,则结点i无双亲,是二叉树的根;如果i>1, 则其双亲是结点i/2 。 (2)如果2i>n,则结点i为叶子结点,无左孩子;否则,其 左孩子是结点2i。 (3)如果2i+1>n,则结点i无右孩子;否则,其右孩子是 结点2i+1。
第六章树和二叉树
6.2 二叉树
二叉树的定义
定义
二叉树是n(n0)个结点的有限集合,它或为空 树(n=0),或由一个根结点和两棵互不相交的左 子树和右子树的二叉树组成。
二叉树的特点:
定义是递归的; 0结点的度2; 是有序树。
二叉树(续)
二叉树的五种基本形态
两种特殊的二叉树
满二叉树:每一层上的结点数都是最大结点数。
树的表示方法
A
B
C
D
EF G
HI
1层 特点:除根结点外, 每个结点都仅有一 个前趋(父)结点。
2层 其它表示方法:
嵌套集合表示法
凹入表表示法
3层
参见教材120页
J
4层
树的一些基本术语
结点的度(degree)
结点所拥有的子树的数目。
叶子结点(leaf--又称终端结点 terminal node)
} }
利用遍历结果确定二叉树问题
利用遍历结果确定二叉树问题
先序序列+中序序列 中序序列+后序序列 先序序列+后序序列 (x)
A
B
F
C
G
先序序列: ABCDEFGH 中序序列: BDCEAFHG
DE H
思考:层序+先序/中序/后序, 能否确定?如何做?
例如:层序ABCDEFGHIJ,中序DBGEHJACIF
} }
void Inorder(BiTree t) {
if (t) { Inorder(t->lchild); visit(t); Inorder(t->rchild);
} }
void Postorder(BiTree t) {
if (t) { Postorder(t->lchild); Postorder(t ->rchild); visit( t );
第六章 树和二叉树
第六章树和二叉树树是一类重要的非线性数据结构,是以分支关系定义的层次结构§6.1 树的定义★定义❖定义:树(tree) 是n(n>0) 个结点的有限集T ,其中:●有且仅有一个特定的结点,称为树的根(root)●当n>1 时,其余结点可分为m(m>0) 个互不相交的有限集T1,T2,……T m,其中每一个集合本身又是一棵树,称为根的子树(subtree)❖特点:●树中最多只有一个根结点●树中各子树是互不相交的集合★基本术语❖结点(node)——表示树中的元素,包括数据项及若干指向其子树的分支❖结点的度(degree)——结点拥有的子树数❖叶子(leaf)——度为0 的结点❖孩子(child)——结点子树的根称为该结点的孩子❖双亲(parents)——孩子结点的上层结点叫该结点的~❖兄弟(sibling)——同一双亲的孩子❖树的度——一棵树中最大的结点度数❖结点的层次(level)——从根结点算起,根为第一层,它的孩子为第二层……❖深度(depth)——树中结点的最大层次数❖森林(forest)——m(m≥0) 棵互不相交的树的集合§6.2 二叉树6.2.1定义定义:二叉树是n(n≥0)个结点的有限集,它或为空树(n=0),或由一个根结点和两棵分别称为左子树和右子树的互不相交的二叉树构成特点每个结点至多有二棵子树(即不存在度大于2的结点)二叉树的子树有左、右之分,且其次序不能任意颠倒★ 6.2.2二叉树性质性质1 :在二叉树的第i层上至多有2i-1个结点(i>=1)性质2:深度为k的二叉树至多有2k -1 个结点(k≥1)性质3:对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1★两种特殊形式的二叉树❖满二叉树●定义:深度为k,顶点个数为2k-1的二叉树叫满二叉树●完全二叉树●定义:深度为k,有n个结点的二叉树当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称为完全二叉树性质4:具有n个结点的完全二叉树的深度为⎣log2n⎦+1⎣ x⎦表示不大于x的最大整数⎡ x⎤表示不小于x的最小整数性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号,则对任一结点i(1≤i≤n),有:(1) 如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是⎣i/2⎦(2) 如果2i>n,则结点i无左孩子;如果2i≤n,则其左孩子是2i(3) 如果2i+1>n,则结点i无右孩子;如果2i+1≤n,则其右孩子是2i+1二叉树的链式存储表示二叉链表typedef struct node{ datatype data;struct node *lchild, *rchild;}treenode,*treelink;三叉链表typedef struct node{ datatype data;struct node *lchild, *rchild, *parent ;}treenode3;使用性质5 建立二叉树#define max 20 ;treelink p[max+1] ;treelink creattree(void){ printf (“input I , ch :”);scanf(“%d,%d”&I,&ch);while (I!=0&& ch!=‘#’){ s=(btreenode*) malloc (sizeof(btreenode));s->data=ch;s->lchild=NULL;s->rchild=NULL;p[I]=s;If (I==1)t=s; //树根else{ j=I/2; //结点I双亲的序号=jif (I%2==0) p[j]->lchild=s;else p[j]->rchild=s;}printf (“input I ch :”);scanf(“%d,%d”&I,&ch);} //endwhilereturn t ;}6.3.1 遍历二叉树一.先根遍历1.递归算法输入:二叉树输出:先根遍历序列1、if(二叉树非空)1.1.访问根结点1.2.先根遍历左子树1.3.先根遍历右子树算法的类C语言描述Viod preorder(treelink t){ if ( t ){ printf( t->data);preorder(t->lchild);preorder(t->rchild);}}2、非递归算法输入:二叉树T输出:先根遍历序列1.初始化栈S2.P指向根结点3. while(栈不空或P不是空指针)3.1.if(P不是空指针)3.1.1.输出P所指结点数据3.1.2. P进栈3.1.3. P指向P所指结点的左孩子3.2.else3.2.1.P=栈顶元素出栈3.2.2.P指向P所指结点的右孩子算法的类C语言描述void preorder2(treelink t){ p=t ;initstack(S);while (p|| !empty(S)){ if (p){ printf(p->data);push(S,p);p=p->lchild;}else{ p=pop(S);p=p-rchild; } }}时间复杂度O(n)二、中根遍历1.递归算法:输入:二叉树输出:中根遍历序列1、if(二叉树非空)1.1.中根遍历左子树1.2.访问根结点1.3.中根遍历右子树算法的类C描述Viod midorder(treelink t){ if ( t ){ midorder(t->lchild);printf( t->data);midorder(t->rchild);}}2、非递归法输入:二叉树T输出:中根遍历序列1.初始化栈S2.P指向根结点3. while(栈不空或P不是空指针)3.1.if(P不是空指针)3.1.1. P进栈3.1.2. P指向P所指结点的左孩子3.2.else3.2.1.P=栈顶元素出栈3.2.2.输出P所指结点数据3.2.3.P指向P所指结点的右孩子4.endwhile算法的类C描述Void midorder2(treelink t){ p=t ;initstack(S);while (p|| !empty(S)){ if (p){ push(S,p);p=p->lchild; }else{ p=pop(S);printf(p->data);p=p-rchild; } }}时间复杂度O(n)三、后根遍历1.递归算法:输入:二叉树输出:后根遍历序列1、if(二叉树非空)1.1.后根遍历左子树1.2.后根遍历右子树1.3.访问根结点算法的类C描述Viod lastorder(treelink t){ if ( t ){ lastorder(t->lchild);lastorder(t->rchild);printf( t->data);}}说明:二叉树的遍历是二叉树其他操作的基础,在对二叉树遍历过程中可以对二叉树的结点进行各种操作:求叶子结点个数,求结点的孩子结点,求结点的双亲结点,求二叉树结点个数,建立二叉树等等。
第六章树与二叉树2-1遍历二叉树
?
先序序列: A, B, D, E, J, C, F, I, G 中序序列: D, B, J, E, A, F, I, C, G
先序序列: A, B, D, E, J, C, F, I, G 中序序列: D, B, J, E, A, F, I, C, G
A
D,B,J, E F,I,C,G
A B D J, E F,I,C,G
viod PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e)) { if (T) { Visit(T->data); PreOrderTraverse(T->lchild, Visit); PreOrderTraverse(T->rchild, Visit); }//if }//PreOrderTraverse void leaf(BiTree T) { if(T) { if (T->lchild==NULL&&T->rchild==NULL) n=n+1; leaf(T->lchild); leaf(T->rchild); }//if }//leaf
先序序列:A
B D C
printf(C); pre(T L); pre(T R);
T
返回
二、遍历的算法描述 先序遍历 非递归算法
算法的关键:在前序遍历过某结点的整个左子树后, 如何找到该结点的右子树的根指针。 解决办法:在访问完该结点后,将该结点的指针保存 在栈中,以便以后能通过它找到该结点的右子树。 在前序遍历中,设要遍历二叉树的根指针为T,则有 两种可能: ⑴ 若T!=NULL,则表明?如何处理? ⑵ 若T=NULL,则表明?如何处理?
第6章树与二叉树-
F3
7
G6
8
H6
9
K6
8
2. 孩子表示法
由于树中每个结点可能有多棵子树,则可以用多重 链表,即每个结点有多个指针域,其中每个指针指向一 棵子树的根结点,此时,链表中的结点可以有如下 3 种 结构格式:
同构结点格式 不同构结点格式 单链表存储结构
9
(1) 同构结点格式。即多重链表中的结点是同构的。
完全二叉树:一棵深度为 k 并且有 n 个结点的二叉 树,当且仅当其每一个结点都与深度为 k 的满二叉树中 编号从 1 至 n 的结点一一对应时,称之为完全二叉树。
完全二叉树的特点是:二叉树中的叶子结点只可能 出现在二叉树中层次最大的两层上;最下一层的结点一 定是从最左边开始向右放的;并且若某个结点没有左孩 子,则它一定没有右孩子。
为 2 的结点有两个出支,则:B = n1 + 2n2 故:n = n1 + 2n2 + 1;最后得到: n0 = n2 + 1。
20
为便于介绍下面两个二叉树性质,先了解满二叉树 (full binary tree) 和完全二叉树 (complete binary tree) 的 概念。
满二叉树:一棵深度为 k 并且有 2k-1 个结点的二叉 树,称之为满二叉树。
23
性质5:如果对一棵有 n 个结点的完全二叉树(此二 叉树的深度为 log2n +1)的结点按照层次编号(从第 1 层到第 log2n +1 层,每层从左到右),那么对任一结点 i(1 ≤i ≤n),有
(1) 若 i = 1,则结点 i 是二叉树的根,没有双亲结点; 若 i >1,则其双亲结点是结点 i / 2。
(2) 若 2i >n,则结点 i 没有左孩子(结点 i 为叶子结 点);否则其左孩子是结点 2i。
数据结构第6章树和二叉树
第6章树和二叉树本章学习要点◆熟悉树的递归定义、相关术语以及基本概念◆熟悉二叉树的递归定义、二叉树的有关术语以及基本概念◆掌握二叉树的基本性质以及相应的证明方法◆了解二叉树的两种存储结构、各种存储方法的特点和适用范围◆熟练掌握二叉树的各种遍历算法,能通过应用二叉树的遍历操作实现二叉树的其它基本操作◆了解线索二叉树的实质和目的,掌握在中序线索化的二叉树中,查找给定结点的前驱和后继的方法◆掌握树、森林与二叉树之间的关系和转换方法◆掌握树的各种存储结构的特点、适应范围以及树和森林的遍历算法树型结构是一种应用非常广泛的非线性结构,其中以二叉树最为常用。
树型结构反映了元素之间的层次关系和分支关系,它非常类似于自然界中的树。
树型结构在计算机领域中广泛应用。
比如,在计算机操作系统中对文件的目录管理就是采用树型结构;在编译程序中,使用树来表示程序的语法结构;在数据库系统中,树型结构也是信息的重要组织形式之一。
本章将详细讨论二叉树的逻辑结构、各种存储结构及其基本操作的实现,研究树、森林和二叉树之间的转换关系,最后介绍一个二叉树的应用实例____Huffman树及其应用。
6.1树的定义和基本术语6.1.1树的定义树T(Tree)是n(n>=0)个数据元素(结点)的有限集合D,如果D为空集,则称T为空树;否则有下面的定义:(1)在D中有且仅有一个特定的结点,称为根结点;(2)当n>1时,其余的结点可分成m(m>0)个互不相交的有限集:T1,T2,…,T m,期中每个集合又都是一棵树,并称它们为树T的根结点的子树。
树是以递归的方式来定义的,即在叙述树的定义的过程中又用到了树的概念。
树的这种递归定义方式反映了树型结构的层次特性。
直观地讲,树是由根结点和若干棵子树组成,其中的每棵子树又都是由一个根结点和它自己的若干棵子树组成,依此类推。
例如,图6.1是用图形表示法表示的一棵树T。
根据树的定义,T的数据元素集合D中一共包含有10个结点:D={A,B,C,D,E,F,G,H,I,J},其中结点A为T的根结点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
•
1 2 4 8 9 5 10 11 6 2 3 4 7 8 9 5
1 3 6 7
10 11 12
32
1 2 4 8 9 10 5 11 12 6 13 14 3 7 15 4 6 2
A ^
C
E
D
F G
E ^
^ G ^
F
^
在n个结点的二叉链表中,有n+1个空指针域
(2)三叉链表
typedef struct BiTNode lchild data parent rchild { TElemType data; struct BiTNode *lchild, *rchild, *parent; } BiTNode ,*Bitree; A ^ ^
1、满二叉树 定义:一棵深度为k且有2k-1个结点的二叉树。 特点:每一层上的结点数都是最大结点数
• •
1 2 4 8 9 10 5 11 12 3 6 13 14 7 15
31
2、完全二叉树
• 定义:深度为 k,有n个结点的二叉树当且仅当其每一个结点 都与深度为k的满二叉树中编号从1至n的结点一一对应时,
38
二叉树的遍历
39
二叉树的链式存储表示
1. 二叉链表 2.三叉链表 3.线索链表
40
(1)二叉链表
typedef struct BiTNode { TElemType data; struct BiTNode *lchild, *rchild; } BiTNode ,*Bitree;
A B ^ C B ^ ^ D
本章重点:二叉树的表示和实现
21
6.2
二叉树
为何要重点研究每结点最多只有两个‚叉‛的树? 二叉树的结构最简单,规律性最强; 可以证明,所有树都能转为唯一对应的二叉树, 不失一般性。 1. 2. 二叉树的定义 二叉树的性质
3.
4.
二叉树的存储结构
二叉树的运算(6.3节)
22
二叉树
二叉树是n(n0)个结点的有限集,它或为空树(n=0),或由一个根 结点和两棵分别称为左子树和右子树的互不相交的二叉树构成。 特点 ① 每个结点至多有二棵子树(即不存在度大于2的结点) ②二叉树的子树有左、右之分,且其次序不能颠倒
论。
而二叉树是非线性结构,每个结点有两个后继,则存在如 何遍历即按什么样的搜索路径遍历的问题。
•
根结点 右子树 左子树
23
五种基本形态
A
A B
A
B B
A C 左、右子树 均非空
空二叉树
只有根结点 的二叉树
右子树为空
左子树为空
问:具有3个结点的二叉树可能有几种不同形态?
有5种
24
二叉树的抽象数据类型定义
ADT BinaryTree{ 数据对象D: D是具有相同特性的数据元素的集合。 数据关系R: 若D=Φ,则R= Φ ; 若D≠Φ,则R= {H};存在二元关系: ① root 唯一 //关于根的说明 ② Dl∩Dr= Φ //关于子树不相交的说明
25
基本操作 P:20个 }ADT BinaryTree
26
二叉树的性质
性质 1 :
在二叉树的第 i 层上至多有2i-1 个结点。(i≥1)
用归纳法证明: 归纳基: i = 1 层时,只有一个根结点:
2i-1 = 20 = 1; 归纳假设: 设i = k-1时成立,最多有2k-2个结点 归纳证明: 二叉树上每个结点至多有两棵子树,
解决思路: 先研究最简单、最有规律的树,然 后设法把一般的树转化为简单树 (二叉树)。
20
树的运算 要明确:
1. 普通树(即多叉树)若不转化为二叉树,则运算很难实现。
2. 二叉树的运算仍然是插入、删除、修改、查找、排序等,
但这些操作必须建立在对树结点能够‚遍历‛的基础上!
遍历——指每个结点都被访问且仅访问一次,不遗漏不重复
(2) 如果2i>n,则结点i无左孩子;如果2i ≤ n,则其左孩子是2i。
(3) 如果2i+1>n,则结点i无右孩子;如果2i+1 ≤ n,则其右孩子 是2i+1。 1
2 4 8 9 5 10 11 12
36
3
6
7
二叉树的存储结构
1、顺序存储结构 实现:按满二叉树的结点层次编号,依次存放二叉树中的数据元 素。 1 2 3 4 5 6 7 8 9 10 特点: a b c d e 0 0 0 0 f 结点间关系蕴含在其存储位置中 浪费空间,适于存满二叉树和完全二叉树 1 2 3 4 5 6 7 8 9 10 1 a 1 2 3 4 5 6 7 8 9 10
• •
11 g 11 11
2 b
4 d 8 9
3
c
1 7
5 e
10 f
6
11 g
2 4
8 9 5 10 11 6
3 7
37
二叉树的顺序存储表示 #define MAX_TREE_SIZE 100 // 二叉树的最大结点数 typedef TElemType SqBiTree[MAX _ TREE_SIZE]; SqBiTree bt; 思考:一个深度为 k 且只有 k 个结点的右单支树需要的数 组存储空间为多少? 显然,这种存储表示方法只适合于完全二叉树,对于一般 的二叉树将造成存储空间的很大浪费。因此二叉树的常用 存储结构是链表。
9
基本操作:
查 找 类
插 入 类 删 除 类
10
查找类:
Root(T) // 求树的根结点 Value(T, cur_e) // 求当前结点的元素值 Parent(T, cur_e) // 求当前结点的双亲结点 LeftChild(T, cur_e) // 求当前结点的最左孩子 RightSibling(T, cur_e) // 求当前结点的右兄弟
12
删除类:
ClearTree(&T) // 将树清空 DestroyTree(&T) // 销毁树的结构
DeleteChild(&T, &p, i) // 删除结点p的第i棵子树
13
基
本
术
语
结点: 数据元素+若干指向子树的分支 结点的度: 分支的个数 树的度: 树中所有结点的度的最大值 叶子结点: 度为零的结点 分支结点: 度大于零的结点
TreeEmpty(T) // 判定树是否为空树 TreeDepth(T) // 求树的深度
TraverseTree( T, Visit() ) // 遍历
11
插入类:
InitTree(&T) // 初始化置空树 CreateTree(&T, definition) // 按定义构造树 Assign(T, cur_e, value) // 给当前结点赋值 InsertChild(&T, &p, i, c) // 将以c为根的树插入为结点p的第i棵子树
第六章
树和二叉树
1
树是常用的数据结构
•家族 •各种组织结构 •操作系统中的文件管理 •编译原理中的源程序语法结构 •信息系统管理 •。。。。
2
树的定义
• 树(tree)是n(n>=0)个结点的有限集T,其中:有且仅有一个特 定的结点,称为树的根(root)。 • 当n>1时,其余结点可分为m(m>0)个互不相交的有限集 T1,T2,……Tm,其中每一个集合本身又是一棵树,称为根的 子树(subtree) A • 特点: ①非空树中至少有一个结点——根 B C D ②树中各子树是互不相交的集合
29
练习:
1. 树T中各结点的度的最大值称为树T的 D 。
A) 高度 B) 层次 C) 深度 D) 度
2.深度为K的二叉树的结点总数,最多为 C 个。
A)2k-1 B) log2k C) 2k-1 D)2k
3. 深度为9的二叉树中至少有 C 个结点。
A)29 B)28 C)9 D)29-1
30
几种特殊形式的二叉树
目录树等等),但只有一个根结点,且子树之 间互不相交。
树的存储结构 讨论1:树是非线性结构,该怎样存储?
——仍然有顺序存储、链式存储等方式。
19
讨论2:树的顺序存储方案应该怎样制定?
可规定为: 从上至下、从左至右将树的结点依次存入内存。 重大缺陷: 复原困难
讨论3:树的链式存储方案应该怎样制定?
可用多重链表:一个前趋指针,n个后继指针。 细节问题: 树中结点的结构类型样式该如何设计? 即应该设计成‚等长‛还是‚不等长‛? 缺点: 等长结构太浪费(每个结点的度不一定相同); 不等长结构太复杂(要定义好多种结构类型)。
14
路径:
由从根到该结点所经分支 和结点构成
结点的层次:
根结点的层次为1,根的孩 子为第二层,第l 层的结点 的子树根结点的层次为l+1
孩子结点、双亲结点 兄弟结点、堂兄弟结点 祖先结点、子孙结点
树的深度: 树中叶子结点所在的最大层次
15
森林:
是m(m≥0)棵互 不相交的树的集合
B E K F L C G H D I J M
7
对比树型结构和线性结构的结构特点
线性结构
第一个数据元素(无前驱)
最后一个数据元素(无后继)
树型结构 根数据元素 (一个前驱、一个后继)
其它数据元素 (一个前驱、多个后继)
8
树的抽象数据类型定义
数据对象 D: D是具有相同特性的数据元素的集合。 数据关系 R: 若D为空集,则称为空树 。 否则: (1) 在D中存在唯一的称为根的数据元素root; (2) 当n>1时,其余结点可分为m (m>0)个互 不相交的有限集T1, T2, …, Tm,其中每一 棵子集本身又是一棵符合本定义的树, 称为根root的子树。