当前位置:文档之家› 数据结构第六章

数据结构第六章

B A
C
if (!StackEmpty(S)){
Pop(S,p); if(!Visit(p->data)) return ERROR; Push(S,p->rchild);} } return Ok; }
G
D
E H
F
I K
J
M
按先序序列建立二叉树的二叉链表的算法 Status CreateBiTree(BiTree &T) { //按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树 scanf(&ch); if (ch==‘’) T=NULL; else { if (!(T=(BiTNode *)malloc(sizeof(BiTNode)))) exit(OVERFLOW); T->data=ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); } return OK; }
(a)
两棵不同的二叉树
(b)
(c) 一棵普通树
6.2.2 二叉树的性质
性质1 二叉树第i层上的结点数目最多为2i-1(i>=1). 性质2 深度为k的二叉树至多有2k-1个结点(k>=1)。
证明:
(第i层上的最大结点数) 2i 1 2k 1
i 1 i 1
k
k
性质3 在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为 n2,则n0 = n2 +1。 证明:设n1为二叉树T中度为1的结点数。因为所有结点的度均小于或等 于2,所以其结点总数为 n=n0+n1+n2 (6.1)
再看二叉树中的分支数。除了根结点外,其余都有一个分支进入,设B 为分支总数,则n=B+1。由于这些分支是由度为1或2的结点射出,所以 又有B=n1+2n2。于是得
n=n1+2n2+1
由式(6-1)和(6-2)得 n0=n2+1 几种特殊形态的二叉树 1、满二叉树 2、完全二叉树
(6.2)
一棵深度为k且含有2k-1个结点的二叉树。
第六章 树和二叉树
举例 1、家谱 6.1 树的定义和术语 2、行政组织结构 3、编译系统中表示源程序的语法结构 树是n(n>0)个结点的有限集合T,它满足如下两个条件: 4、数据库系统中组织信息 (1)有且仅有一个特定的称为根ROOT的结点。 (2)其余结点可分为m(m>=0)个互不相交的有限集合 T1,T2,…,Tm,其中每个集合又都是一棵树,并称其为根的子树 (SubTree)。 树的递归定义刻画了树的固有特性,即一棵树是由若干棵子树 构成的,而子树又可由若干棵更小的子树构成。
B E
C F
D
G
H
I
J
A 3、分支结点 度不为0的结点。 B 4、结点的孩子 结点的子树的根。 E 该结点称为孩子的双亲。 同一个双亲的孩子之间互称兄弟。 结点的祖先是从根到该结点所经分 支上的所有结点。 以某结点为根的子树中的任一结点 都称为该结点的子孙。 C F D
G
H
I
J
分支结点为 J结点的祖先 A、B、D和F 为A、B、F。
7、树的高度或深度
树中结点的最大层次称为树的高度。 8、有序树和无序树 若将树中结点的各子树看成从左 到右有次序的,则称该树为有序树, 否则称为无序树。 9、森林 森林是m棵互不相交的树的集合。 对树中每个结点而言,其子树的集合 即为森林。因此,可以用森林和树相 互递归的定义来描述树。 E B C
如输入字符: A B C $ $ D E $ G $ $ F $ $ $
A T={A,B,C,D,E,F,I,J},其中A 是根结点 T1={B,E,F,I,J} T2={C} E B C D G H
F
T3={D,G,H}
T11={E} T12={F,I,J}
I
J
图6.1树的示例
树的不同表示方法:
1、用嵌套集合表示 2、用广义表表示 A(B(E,F(I,J)),C,D(G,H))
若一棵二叉树至多只有最下面的两层上结点的度数可以小 于2,并且最下层上的结点都集中在该层最左边的若干位置上。
1
1 3
2
满二叉 完全二 树
叉树
7 4 1 5
2
3
4
5
6
5
6
7
8
9
1 0
11
12
1 3
14
8
9
1 0
11
12
1 3
(a)
1
(b)
1
2
3
非完全 二叉树
2
3
4
5
4
6 7
5
6
(c)
(d)
性质4 具有n个结点的完全二叉树的深度为 log2 n 1 证明:假设深度为k,则根据性质2和完全二叉树的定 义有:
6.3遍历二叉树和线索二叉树
6.3.1遍历二叉树
所谓遍历二叉树,就是按某条搜索路径巡访树中每个结点,使得每个结 点均被访问一次,而且仅被访问一次。 六种遍历方法:DLR、LDR、LRD、DRL、RDL、RLD。 其中L、D、R分别表示遍历左子树、访问根结点 和遍历右子树。 下面限定从左到右,则只有三种情况,分别为:先(根)序遍历、中(根)序 遍历、后(根)序遍历。
在完全二叉树,可以从一 个结点的编号就可推知其双 亲、左孩子、右孩子、兄弟 等结点的编号。
1 2 4 6 5 7 3
1
ቤተ መጻሕፍቲ ባይዱ
2
3
4
5
0
0
0
0
6
7
一般二叉树
二、链式存储结构
由二叉树的定义得知,其结点由一个 数据元素和分别指向其左、右子树的两 个分支构成,因此,表示二叉树的链表 中的结点至少包含三个域:数据域和左 右指针域。二叉链表 为了便于找到结点的双亲,还可在结 点结构中增加一个指向其双亲结点的指 针域。 三叉链表 二叉链表的定义: typedef struct BiTNode { TElemType data; struct BiTNode *lchild, *rchild; LCHILD
Status InOrderTraverse(BiTree T, Status (*visit)(TElemType e))
{ InitStack(S); Push(S,T); While(!StackEmpty(S)) { while (GetTop(S,p) && p) Push(S, p->lchild); //向左走到头 Pop(S,p); //空指针退栈
2
于是:
k 1
1 n 2 1或2
k
k 1
n2
k
k 1 log2 n k
因为k是整数,所以k= log2 n 1 注:符号 x 表示不大于x的最大整数,反之, x 表示不小于x的 最小整数。
性质5 如果对一棵有n个结点的完全二叉树的结点按层序编号, 则对任一编号为i的结点ki(1=<i<=n) ,有:
基本操作:
1.Status CreateBiTree(BiTree &T); 2.Status PreOrderTraverse(BiTree T,Status (*visit)(TElemType e)); 3.Status InOrderTraverse(BiTree T,Status (*visit)(TElemType e)); 4.Status PostOrderTraverse(BiTree T,Status (*visit)(TElemType e)); 5.Status LevelOrderTraverse(BiTree T,Status (*visit)(TElemType e));
数据结构类型定义为:
#define MAX_TREE_SIZE 100 Typedef TElemType SqBiTree[MAX_TREE_SIZE]; SqBiTree bt; 完全二叉树
1 2
8
4 2
1 3
5 1 1 1 2
6
7
9
10
3
4
5
6
7
8
9
10 11 12
顺序存储结构仅适用于完全二 叉树。在最坏情况下,一个深度为 k且只有k个结点的单支树(树中 不存在度为2的结点)却需要长度 为2k-1的一维数组。
A
3、凹入表示法 B
E
I F A C C D G G H F J B I E J
A B C F D G H
E
D H
I
J
A 基本术语: 1、结点的度(Degree) 一个结点的子树个数。 一棵树中结点度的最大值称为该树 的度。 2、叶子(Leaf) 也称为终端结点,其度为0。
A的度为3, 树的度为3 C、E、I、J、G、 H的度为0。
H I K
J
M
DLR:ABDGHJKECFIM
LDR:GDJHKBEACFMI
LRD:GJKHDEBMIFCA
先序遍历二叉树基本操作的递归算法在二叉链表上的实现。 Stautus PreOrderTraverse(BiTree T,Status(* Visit)(TElemType e)) { //最简单的Visit函数是: // Status PrintElement(TElemType e) { // printf(e); // return OK; } // 调用实例:PreOrderTraverse( T, PrintElement ); If (T) { if (Visit(T->data)) if (PreOrderTraverse(T->lchild,Visit)) if (PreOrderTraverse(T->rchild,Visit)0 return OK; return ERROR; } else return OK; }//PreOrderTraverse
相关主题