《程序设计实践》第07练——二叉树遍历
- 二叉树遍历:bTree1.cpp(本题50分)
【题目描述】 已知二叉树的先序遍历序列和中序遍历序列,输出其后序遍历序列和层次序遍历序列。
【输入】
输入文件bTree1.in有两行,分别是二叉树的先序遍历序列和中序遍历序列。
【输出】
输出文件bTree1.out包含两行,分别是上述二叉树的后序遍历序列和层次序遍历序列。
【输入输出样例1】
bTree1.in bTree1.out
abdeijfcgh
dijefbghca jifedhgcba
abdcegifhj
【输入输出样例2】
bTree1.in bTree1.out
fniabdckgjmeh
aidbnkcfmjehg adbikcnmhejgf
fngicjabkmedh
图1 样例1对应的二叉树 图2 样例2对应的二叉树
【数据限制】
所有序列字串长度<=100。
【提示】
设计一个算法层序遍历二叉树(同一层从左到右访问)。
思想:用一个队列保存被访问的当前节点的左右孩子以实现层序遍历。
void HierarchyBiTree(BiTree Root){
if (Root == NULL) return ; // 树为空则返回
LinkQueue *Q; // 保存当前节点的左右孩子的队列 用数组来模拟
InitQueue(Q); // 初始化队列
BiNode *p = Root; // 临时保存树根Root到指针p中
while(!QueueEmpty(Q)) { // 若队列不空,则层序遍历
DeQueue(Q, p); // 出队列
Visit(p->data); // 访问当前节点
if (p->lchild) EnQueue(Q, p->lchild); // 若存在左孩子,左孩子进队列
if (p->rchild) EnQueue(Q, p->rchild); // 若存在右孩子,右孩子进队列
}
DestroyQueue(Q); // 释放队列空间
return ;
}
在这里插入代码片
#include "stdio.h"
#include "string.h"
const int N0=100;
struct node{
//二叉树节点
char data; //节点数据(一个字符)
int lch, rch; //二叉树的左子树\右子树
}tree[N0+1];
void createTree( int root, char *pri, char *mid){
//创建二叉树(root-根节点编号; pri-先序字符串序列首指针; mid-中序字符串序列首指针)
char *p; //p-字符串序列 游标
int k; //左子树的节点数目
if( root==0 || *pri=='\0' || *mid=='\0'){
//root==0树为空, 先序字符串序列为空? 中序字符串序列为空?
return;
}
/*(1)树的根节点(data:字符, id:一个No.=1) */
tree[root].data=*pri; //先序字符串序列的第一个节点为根节点
/*(2)在中序字符串序列中查找根节点的位置, 其前为左子树, 其后为右子树*/
p=strchr(mid, *pri ); //strchr函数原型:extern char *strchr(const char *s,char c);查找字符串s中首次出现字符c的位置的指针
/*(3)中序字符串序列中, 将根节点数据(字符)置为空, 以便区分出 "左 & 右 子树" 的中序字符串序列*/
*p='\0'; // 中字符串序列序, 左:0 ~ (p-1), 右:(p+1) ~ END
/*(4)通过中字符串序列序, 获得左子树的长度 */
k=strlen(mid); // 知道了左子树的长度, 那么 先序符串序列序中, 左子树: (pri+1) ~ (pri+k); 右子树: (pri+k+1) ~ END
/*(5.1)通过递归调用, 创建左子树&右子树*/
if( k > 0 ){
//若左子树非空, ...
tree[root].lch = root+1; //左子树根节点->root+1
createTree(root+1, pri+1, mid); //函数createTree(...)递归调用-->创建左子树(注意:先 & 中序 字符串序列)
}
if( strlen(p+1) > 0 ) {
//若右子树非空, ...
tree[root].rch = root+k+1; //右子树根节点->root+k+1
createTree(root+k+1, pri+k+1, p+1); //函数createTree(...)递归调用-->创建右子树(注意:先 & 中序 字符串序列)
}
}
void postOrder( int root ) {
//以root为根节点的二叉树(子树)的 - 后序字符串序列首指针
//******************************************
if( root ) {
//若存在...
postOrder( tree[root].lch ); //后序遍历 左子树
postOrder( tree[root].rch ); //后序遍历 右子树
printf("%c", tree[root].data); //遍历根节点
}
//******************************************
}
void layerOrder( int root ) {
//以root为根节点的二叉树(子树)的 - 按层序方式输出二叉树遍历字符串序列首指针
if( root==0 ){
//若为空树,则返回
return ;
}
/*(*)用一个队列保存被访问的当前节点的左右孩子以实现层序遍历。*/
int qu[N0+1], f