5_树和二叉树
t->c[i]=creaTree(); return t;
3度树,#代表NULL,建树输入序列为:
ABE###F####C###DGI## #J###K###H####
}
编程:建树,并返回树根和该树中结点数量。
要知其然,更要知其所以然。
13/65
m度树的前序遍历建树算法
tree * creaTree (){
if (t->c[i]!=NULL){ printf(","); kuohao(t->c[i]);}
A( B, C( F,G,H), D, E(J,I) )
printf(")");
}
要知其然,更要知其所以然。
20/65
算法:括号表示转孩子指针表示
假定m度树t的括号表示存于a[0..len-1]中。
void creaTree ( tree **t ){
int i; tree* t;
int i;
char c=getchar();
char c=getchar();
if (c=='#') return NULL; if (c=='#' ) { *t=NULL; return; }
t= malloc(sizeof(tree)); *t=malloc(sizeof(tree));
8 I -1 -1 -1
9 J -1 -1 -1
10 K -1 -1 -1
要知其然,更要知其所以然。
7/65
树的存储结构:孩子指#d针efin表e m示3 法
A
B CD
EF G
H
IJK
typedef struct k{ char data; struct k* c[m];
} tree; root
A
分析:括号表示转孩子指针表示,实质是根据括号表示建树。根 据树的定义,建树必须区分出根和子树,怎样区分?
括号表示中含:字母、"("、")"、","等字符,遇到各表示何种含义?
1B
4
2 C∧
3D
6
4 E∧
typedef struct { char data; childNode *firstChild;
} treeNode;
5 F∧
6G
8
7 H∧
8 I∧
typedef struct {
9 J∧
node treelist [M]; int length, r、树的 深度或高度
JK
4、树枝、路径及其长度
有关树的更多性质参见
5、有序树、无序树、森林 《离散数学》相关内容。
要知其然,更要知其所以然。
4/65
1.2 树的逻辑结构和存储结A构
B
CD
树型结构的逻辑描述
E
F
G HI
JK
a. 括号表示法
A(B(E,F),C,D(G,H(J,K),I))
特点: "("前面的元素一定 括号表示:
A(B,C(F,G,H),D,E(J,I))
为某棵树或子树的根结点。
要知其然,更要知其所以然。
18/65
算法:输出树的括号表示 A B C DE
括号表示规则:
1、空树不表示; 2、若树t只有根,则K(t)=A; 3、否则, K(t)=A( K(T1) ,K(T2),…, K(Tm) )
m度树的前序遍历建树算法
tree * creaTree (){ int i; tree* t; char c=getchar(); if (c=='#') return NULL; t= malloc(sizeof(tree));
A
B CD
EF G
H
IJK
t->d=c; for (i=0; i<m; i++)
江西师范大学·计算机信息工程学院·计算机科学系
目录
第1章 绪论和预备知识 第2章 线性表 第3章 字符串、数组和特殊矩阵 第4章 递归技术 第5章 树和二叉树 第6章 图 第7章 检索 第8章 内排序
要知其然,更要知其所以然。
2/65
第5章 树和二叉树
树
本章重点
基本概念和术语 逻辑和存储结构 遍历及线性表示
0、空则返回; 1、输出左括号"("; 2、输出第1个非空孩子; 3、对其余非空孩子,按:
",孩子" 形式输出; 4、输出右括号")".
while(i<m && t->c[i]==NULL) i++; if (i>=m) return; //无子则返回 printf("( "); kuohao(t->c[i]); i++; for(i=i; i<m; i++)
kuohao(t->c[i]);
printf(","); } printf(")"); }
优化使 其符合 预期。
要知其然,更要知其所以然。
19/65
算法:输出树的括号表示 void kuohao(tree *t){ int i=0;
美化输出算法思想
if (t==NULL) return; printf("%c ", t->d);
p=出队元素;
p=outQueue(Q);
访问p;
Visit(p);
p的所有非空孩子依次入队;
p的所有孩子依次入队;
}
}
}
要知其然,更要知其所以然。
15/65
算法:输出树的凹入表示
B
E
F
A
C
D
G HI
JK
分析:
1、自上而下输出有何规律? 2、包含空格、字符、#,且每行 总长固定。空格数如何变化?
A
B ^ C^^^ D ^
E^^^ F^^^ G
H ^^^
I^^^ J^^^ K^^^
要知其然,更要知其所以然。
8/65
树的A存储结构:孩子链表表示法
B CD
EF G
H
IJK
root
data firstChild
0A
1
# define M 50 typedef struct c {
int child; struct c* next; } childNode;
5F 1
6G 3
7H 3
8I 6
9J 6
10 K 6
要知其然,更要知其所以然。
6/65
树的存储结构:孩子数组表示法
A BC EF G
IJ
#define M 100 #define m 3 typedef struct {
char data; int c[m]; } node;
data c[0] c[1] c[2]
二叉树 基本概念和性质 存储结构 遍历和相关算法
1. 掌握树的链式存储结构,以及树 的各种遍历算法;
2. 掌握二叉树的相关基本性质; 3. 掌握二叉树遍历的递归算法,以
及前序、中序的非递归算法、 4. 掌握二叉树与树/森林相互转换;
穿线树、二叉树和树/森林间的相互转换
要知其然,更要知其所以然。
凹
B
入
E
表
F
示
C
法
D
G
H
J
K
I
要知其然,更要知其所以然。
16/65
算法:输出树的凹入表示
B
E
F
A
C
D
G HI
JK
总体采用前序遍历:
算 if ( t==NULL) return; 法 输出根; 思 调整空格和#号数量, 想 按相同方式
输出所有孩子;
void aoruOut(tree * t, int kg, int jh){ int i;//kg:空格数,jh:#数 if (t==NULL) return; /*下面四行输出根*/ for(i=1; i<=kg; i++) printf(" "); printf("%c ",t->d); for(i=1; i<=jh; i++) printf("##"); printf("\n"); for(i=0; i<m; i++)//输出所有孩子 aoruOut(t->c[i], kg+2, jh-2);
}
要知其然,更要知其所以然。
17/65
树的线性表示:括号表示
假定t由根A和其m棵子树T1,T2,……Tm构成,K(t)是t的括号表示
括号表示规则:
1、空树不表示; 2、若树t只有根,则K(t)=A; 3、否则, K(t)=A( K(T1) ,K(T2),…, K(Tm) )
A B C DE
FGHJ I
层次遍历:空树返回;否则从根开始从上至下从左至右逐层遍历各个结点。
A
B CD
EF G
H
IJK
前序遍历:ABEFCDGIJKH
后序遍历:EFBCIJKGHDA
层次遍历:ABCDEFGHIJK
关键:类似于以 ab+ 作为公 式书写逆波兰式。
要知其然,更要知其所以然。
11/65
m度树的前序/后序遍历算法
(C) A
(b) 嵌套 集合 表示 法
A C
B EF
D G
I
HK J
B
凹
E