A - 算法与数据结构实验4:二叉树操作
根据给定的字符串生成二叉树并前序、中序、后序此二叉树。
Input
给定一字符串,其中#表示空。
例:上图输入为
HDB#A##C##G#FE###
Output
分别输出此二叉树前序、中序和后序。
Sample Input
HDB#A##C##G#FE###
Sample Output
HDBACGFE
BADCHGEF
ABCDEFGH
#include<iostream>
#include <algorithm>
#include <cstdlib>
#include<cstdio>
#include<cstring>
#include <cmath>
using namespace std;
const int M=200000+10;
const int MAX=0x3f3f3f3f;
typedef long long ll;
typedef struct node
{
char data;
struct node *lchild,*rchild;
}BinTree;
BinTree *Create()
{
BinTree *bt=NULL;
char ch;
ch=getchar();
if(ch!='#')
{
bt=(BinTree *)malloc(sizeof(BinTree));
bt->data=ch;
bt->lchild=Create();
bt->rchild=Create();
}
return bt;
}
BinTree ONE(BinTree *bt)
{
if(bt!=NULL)
{
printf("%c",bt->data);
ONE(bt->lchild);
ONE(bt->rchild);
}
}
BinTree TWO(BinTree *bt)
{
if(bt!=NULL)
{
TWO(bt->lchild);
printf("%c",bt->data);
TWO(bt->rchild);
}
}
BinTree THREE(BinTree *bt)
{
if(bt!=NULL)
{
THREE(bt->lchild);
THREE(bt->rchild);
printf("%c",bt->data);
}
}
int main()
{
BinTree *bt;
bt=Create();
ONE(bt);
printf("\n");
TWO(bt);
printf("\n");
THREE(bt);
printf("\n");
return 0;
}
B - 树与二叉树
遍历一棵二叉树就是按某种次序系统地“访问”二叉树上的所有结点,并使每一个结点恰好被访问一次。所谓“访问”一个结点,是指对该结点的数据域进行某种处理,处理的内容依具体问题而定,通常比较简单。我们知道,遍历一个线性结构很容易,只须从开始结点出发顺序扫描每个结点即可。但是二叉树是一个非线性结构,每个结点可以有两个后继结点,因此需要寻找一种规律来系统地访问树中各结点。遍历运算的关键在于访问结点的“次序”,这种次序应保证二叉树上的每个结点均被访问一次且仅一次。
由定义可知,一棵二叉树由三部分组成:根、左子树和右子树。因此对于二叉树的遍历也可相应地分解成三项“子任务”:
①访问根结点;
②遍历左子树(即依次访问左子树上的全部结点);
③遍历右子树(即依次访问右子树上的全部结点)。
因为左、右子树都是二叉树(可以是空二叉树),对它们的遍历可以按上述方法继续分解,直到每棵子树均为空二叉树为止。由此可见,上述三项子任务的次序决定了遍历的次序。若以D、L、R分别表示这三项子任务,则共有6种可能的次序:DLR、LDR、LRD、DRL、RDL和RLD。通常限定“先左后右”,即子任务②在子任务③之前完成,这样就只剩下前三种次序,按这三种进行的遍历分别称为先根遍历(或前序遍历)、中根(或中序)遍历、后根(或后序)遍历。三种遍历方法的定义如下。
先根遍历 若需遍历的二叉树为空,执行空操作;否则,依次执行下列操作:
①访问根结点;
②先根遍历左子树;
③先根遍历右子树。
中根遍历 若需遍历的二叉树为空,执行空操作;否则,依次执行下列操作:
①中根遍历左子树;
②访问根结点;
③中根遍历右子树。
后根遍历 若需遍历的二叉树为空,执行空操作;否则,依次执行下列操作:
①后根遍历左子树;
②后根遍历右子树;
③访问根结点。
显然,上述三种遍历方法的区别在于执行子任务“访问根结点”的“时机”不同;若最先(最后、在中间)执行此子任务,则为先根(后根、中根)遍历。
按某种遍历方法遍历一棵二叉树,将得到该二叉树上所有结点的访问序列。
Input
输入的第一行包含单独的一个数字T,表示测试序列的数目;
以下T个部分,每个部分一个测试序列;
每个测试序列的第一行包含一个整数N(0 < N ≤ 1000),表示二叉树的节点数;
接下来N行,每行按照这样如下的格式依次描述每个节点:
字符数据 左孩子序号 右孩子序号
其中节点的字符数据是一个单字符,如果左/右孩子不存在,用0表示其序号。
Output
对应每个测试序列,输出以下四行:
Case #: '#'是从一开始的测试序列号;
先序遍历的结果
中序遍历的结果
后序遍历的结果
Sample Input
2
8
* 2 3
+ 4 5
- 0 6
x 0 0
y 0 0
/ 7 8
a 0 0
2 0 0
3
+ 2 3
2 0 0
3 0 0
Sample Output
Case 1:
*+xy-/a2
x+y*-a/2
xy+a2/-*
Case 2:
+23
2+3
23+
#include<iostream>
#include <algorithm>
#include <cstdlib>
#include<cstdio>
#include<cstring>
#include <cmath>
using namespace std;
const int M=200000+10;
const int MAX=0x3f3f3f3f;
typedef long long ll;
typedef struct Bitnode
{
char data;
struct Bitnode *lchild,*rchild;
} *BinTree,Bitnode;
struct T
{
int l;
int r;
}child[1010];
void ONE(BinTree bt)
{
if(bt!=NULL)
{
printf("%c",bt->data);
ONE(bt->lchild);
ONE(bt->rchild);
}
}
void TWO(BinTree bt)
{
if(bt!=NULL)
{
TWO(bt->lchild);
printf("%c",bt->data);
TWO(bt->rchild);
}
}
void THREE(BinTree bt)
{
if(bt!=NULL)
{
THREE(bt->lchild);
THREE(bt->rchild);
printf("%c",bt->data);
}
}
int main()
{
int t,n,k,i,j;
char c,a,b;
cin>>t;
BinTree node[1010];
for(i=1; i<=t; i++)
{
BinTree bt;
cin>>n;
for(j=1;j<=n;j++)
{
cin>>c>>child[j].l>>child[j].r;
node[j]=(BinTree)malloc(sizeof(Bitnode));
node[j]->data=c;
}
bt=node[1];
for(j=1;j<=n;j++)
{
if(child[j].l!=0)
node[j]->lchild=node[child[j].l];
else
node[j]->lchild=NULL;
if(child[j].r!=0)
node[j]->rchild=node[child[j].r];
else
node[j]->rchild=NULL;
}
cout<<"Case "<<i<<":"<<endl;
ONE(bt);
cout<<endl;
TWO(bt);
cout<<endl;
THREE(bt);
cout<<endl;
}
return 0;
}