目录
一、树的遍历
1.1 先根遍历
1.1.1 算法思想
若树非空,则遍历方法为:
1、访问根结点;
2、从左到右,依次先根遍历根结点的每一棵子树。
树的先根遍历 <=> 转换后二叉树的先序遍历
如图所示:
1.1.2 算法实现
/* 先根遍历 */
void RootFirst(CSTree root, CALLBACK Visit) {
if (!root) return;
Visit(root->data);
RootFirst(root->FirstChild, Visit);
RootFirst(root->NextSibling, Visit);
}
1.2 后根遍历
1.2.1 算法思想
若树非空,则遍历方法为:
1、从左到右,依次后根遍历根结点的每一棵子树;
2、访问根结点。
树的后根遍历 <=> 转换后二叉树的中序遍历
如图所示:
1.2.2 算法实现
/* 后根遍历 */
void RootLast(CSTree root, CALLBACK Visit) {
if (!root) return;
RootLast(root->FirstChild, Visit);
Visit(root->data);
RootLast(root->NextSibling, Visit);
}
二、树的遍历算法应用
2.1 树的创建
根据先根/先序定位串创建树。
CSTree _CreateCSTree(char **s) {
if (**s == '\0') return NULL;
if (**s == '.') {
++ *s;
return NULL;
}
CSTree root = (CSTree)malloc(sizeof(CSNode));
root->data.tag = **s;
++ *s;
root->FirstChild = _CreateCSTree(s);
root->NextSibling = _CreateCSTree(s);
return root;
}
2.2 树的销毁
后序遍历销毁树。
void DestroyCSTree(CSTree root) {
if (!root) return;
DestroyCSTree(root->FirstChild);
DestroyCSTree(root->NextSibling);
free(root);
}
三、森林的遍历
对照二叉树与森林之间的转换关系可以发现,森林的先序遍历、中序遍历和后序遍历与其相应二叉树的先序遍历、中序遍历和后序遍历是对应相同的。因此,对森林的遍历可以转换为对其相应二叉树的遍历。
示例:
3.1 先序遍历
3.1.1 算法思想
若森林非空,则遍历方法为:
1、访问森林中第一棵树的根结点;
2、先序遍历第一棵树的根结点的子树森林;
3、先序遍历除去第一棵树之后剩余的树构成的森林。
3.1.2 算法实现
/* 先序遍历 */
void ForestPre(Forest f, CALLBACK visit) {
if (!f) return;
visit(f->data);
ForestPre(f->FirstChild, visit);
ForestPre(f->NextSibling, visit);
}
3.2 中序遍历
3.2.1 算法思想
若森林非空,则遍历方法为:
1、中序遍历第一棵树的根结点的子树森林;
2、访问森林中第一棵树的根结点;
3、中序遍历除去第一棵树之后剩余的树构成的森林。
3.2.2 算法实现
/* 中序遍历 */
void ForestIn(Forest f, CALLBACK visit) {
if (!f) return;
ForestIn(f->FirstChild, visit);
visit(f->data);
ForestIn(f->NextSibling, visit);
}
3.3 后序遍历
3.3.1 算法思想
若森林非空,则遍历方法为:
1、后序遍历第一棵树的根结点的子树森林;
2、后序遍历除去第一棵树之后剩余的树构成的森林;
3、访问森林中第一棵树的根结点。
3.3.2 算法实现
/* 后序遍历 */
void ForestPost(Forest f, CALLBACK visit) {
if (!f) return;
ForestPost(f->FirstChild, visit);
ForestPost(f->NextSibling, visit);
visit(f->data);
}
四、森林的遍历算法应用
4.1 森林的创建
示意图:
Forest CreateForest(char *f[], int n) {
Forest forest;
/* 生成新森林 */
forest = (Forest)malloc(sizeof(CSNode));
forest->NextSibling = NULL;
CSTree t;
for (int i = 0; i < n; ++i) {
CSTree root = CreateCSTree(f[i]);
if (i == 0)
forest->FirstChild = root;
else
t->NextSibling = root;
t = root;
}
return forest;
}
4.2 森林的销毁
森林就相当于一棵树。
void DestroyForest(Forest f) {
DestroyCSTree(f);
}