A - 数据结构实验之二叉树一:树的同构
Description
给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
图1
图2
现给定两棵树,请你判断它们是否是同构的。
Input
注意:题目保证每个结点中存储的字母是不同的。
Output
Sample
Input
8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -
Output
Yes
Hint
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Tree int
#define Null -1
#define maxsize 10
typedef struct TreeNode
{
char data;
int left;
int right;
}treenode;
treenode T1[maxsize],T2[maxsize];
Tree creattree(treenode T[],int n)
{
int check[100];
char cl,cr,s[10],sl[10],sr[10];
int root=Null;
for(int i=0;i<n;i++){
check[i]=0;
}
for(int i=0;i<n;i++){
scanf("%s %s %s",s,sl,sr);
T[i].data = s[0];
cl = sl[0];
cr = sr[0];
if(cl!='-'){
T[i].left = cl - '0';
check[T[i].left]=1;
}
else{
T[i].left = Null;
}
if(cr!='-'){
T[i].right = cr - '0';
check[T[i].right]=1;
}
else{
T[i].right = Null;
}
}
for(int i=0;i<n;i++){
if(!check[i]){
root=i;
break;
}
}
return root;
}
int isomorphic(Tree R1,Tree R2)
{
if(R1==Null && R2==Null){
return 1;
}/*两棵树都为空*/
if((R1==Null && R2!=Null) || (R2!=Null && R1==Null)){
return 0;
}/*一棵树为空,一棵树不为空*/
if(T1[R1].data != T2[R2].data){
return 0;
}/*两棵树树根不同*/
if(T1[R1].left == Null && T2[R2].left == Null){
return isomorphic(T1[R1].right,T2[R2].right);
}/*两棵树左子树为空,递归右子树*/
if((T1[R1].left !=Null && T2[R2].left!=Null) && (T1[T1[R1].left].data == T2[T2[R2].left].data)){
return (isomorphic(T1[R1].left,T2[R2].left) && isomorphic(T1[R1].right,T2[R2].right));
}/*两棵树左子树不为空且相等,递归右子树*/
else{
return (isomorphic(T1[R1].left,T2[R2].right) && isomorphic(T1[R1].right,T2[R2].left));
}
}
int main()
{
int n1,n2,R1,R2;
while(scanf("%d",&n1)!=EOF){
R1=creattree(T1,n1);
scanf("%d",&n2);
R2=creattree(T2,n2);
if(isomorphic(R1,R2)){
printf("Yes\n");
}
else{
printf("No\n");
}
}
return 0;
}
数据结构实验之二叉树二:遍历二叉树
Description
已知二叉树的一个按先序遍历输入的字符序列,如abc,,de,g,,f,,, (其中,表示空结点)。请建立二叉树并按中序和后序的方式遍历该二叉树。
Input
连续输入多组数据,每组数据输入一个长度小于50个字符的字符串。
Output
每组输入数据对应输出2行:
第1行输出中序遍历序列;
第2行输出后序遍历序列。
Sample
Input
abc,,de,g,,f,,,
Output
cbegdfa
cgefdba
Hint
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int k = 0;
char str[51];
typedef struct TreeNode
{
char data;
TreeNode *lefttree;
TreeNode *righttree;
}Tree;
Tree *creattree(Tree *T)
{
char ch = str[k++];
if(ch==','){
T=NULL;
}
else{
T=(Tree *)malloc(sizeof(Tree));
T->data = ch;
T->lefttree = creattree(T->lefttree);
T->righttree = creattree(T->righttree);
}
return T;
}
void inorder(Tree *T)
{
if(T!=NULL){
inorder(T->lefttree);
printf("%c",T->data);
inorder(T->righttree);
}
}
void postorder(Tree *T)
{
if(T!=NULL){
postorder(T->lefttree);
postorder(T->righttree);
printf("%c",T->data);
}
}
int main()
{
Tree *T;
while(scanf("%s",str)!=EOF){
T=creattree(T);
inorder(T);
printf("\n");
postorder(T);
printf("\n");
memset(str,0,sizeof(str));
k = 0;
}
}
C - 数据结构实验之二叉树三:统计叶子数
Description
已知二叉树的一个按先序遍历输入的字符序列,如abc,,de,g,,f,,, (其中,表示空结点)。请建立二叉树并求二叉树的叶子结点个数。
Input
连续输入多组数据,每组数据输入一个长度小于50个字符的字符串。
Output
输出二叉树的叶子结点个数。
Sample
Input
abc,,de,g,,f,,,
Output
3
Hint
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int k = 0,count = 0;
char str[51];
typedef struct Tree
{
char data;
Tree *lefttree;
Tree *righttree;
}tree;
tree *creattree(tree *T)
{
char ch = str[k++];
if(ch==','){
T=NULL;
}
else{
T=(tree *)malloc(sizeof(tree));
T->data = ch;
T->lefttree = creattree(T->lefttree);
T->righttree = creattree(T->righttree);
if(T->lefttree==NULL && T->righttree==NULL){
count++;
}
}
return T;
}
int main()
{
tree *T;
while(scanf("%s",str)!=EOF){
T=creattree(T);
printf("%d\n",count);
memset(str,0,sizeof(str));
k = 0;
count = 0;
}
}
数据结构实验之二叉树四:(先序中序)还原二叉树
Description
给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。
Input
输入数据有多组,每组数据第一行输入1个正整数N(1 <= N <= 50)为树中结点总数,随后2行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区分大小写)的字符串。
Output
输出一个整数,即该二叉树的高度。
Sample
Input
9
ABDFGHIEC
FDHGIBEAC
Output
5
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct TreeNode
{
char data;
TreeNode *lchild;
TreeNode *rchild;
}Treenode;
Treenode *creattree(int len,char *pre,char *in)
{
Treenode *root;
root = NULL;
if(len>0){
int llen=0,rlen=0;
root=(Treenode *)malloc(sizeof(Treenode));
root->data=pre[0];
char *s;
for(s=in;s!=NULL;s++){
if(*s==*pre){
break;
}
else{
llen++;
}
}
rlen=len-llen-1;
root->lchild=creattree(llen,pre+1,in);
root->rchild=creattree(rlen,pre+llen+1,s+1);
}
return root;
}
int posttreedepth(Treenode *root)
{
int hl,hr,maxh;
if(root==NULL){
return 0;
}
else{
hl = posttreedepth(root->lchild);
hr = posttreedepth(root->rchild);
maxh = hl>hr? hl+1:hr+1;
return maxh;
}
}
int main()
{
int n;
Treenode *T;
while(scanf("%d",&n)!=EOF){
char str1[51],str2[51];
scanf("%s",str1);
scanf("%s",str2);
T = creattree(n,str1,str2);
printf("%d\n",posttreedepth(T));
}
return 0;
}
E - 数据结构实验之二叉树五:层序遍历
Description
已知一个按先序输入的字符序列,如abd,,eg,,,cf,,,(其中,表示空结点)。请建立二叉树并求二叉树的层次遍历序列。
Input
Output
Sample
Input
2
abd,,eg,,,cf,,,
xnl,,i,,u,,
Output
abcdefg
xnuli
Hint
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int k = 0;
char str[51];
typedef struct TreeNode
{
char data;
TreeNode *lchild;
TreeNode *rchild;
}Treenode;
TreeNode *creattree(TreeNode *T)
{
char ch = str[k++];
if(ch==','){
T = NULL;
}
else{
T=(TreeNode *)malloc(sizeof(TreeNode));
T->data=ch;
T->lchild=creattree(T->lchild);
T->rchild=creattree(T->rchild);
}
return T;
}
void travel(TreeNode* T)
{
TreeNode *temp[51];
int front = 0;
int rear = 0;
temp[rear++] = T;
while(rear>front){
if(temp[front]){
printf("%c",temp[front]->data);
temp[rear++] = temp[front]->lchild;
temp[rear++] = temp[front]->rchild;
}
front++;
}
printf("\n");
}
int main()
{
int n;
TreeNode *T;
scanf("%d",&n);
while(n--){
scanf("%s",str);
T=creattree(T);
travel(T);
memset(str,0,sizeof(str));
k = 0;
}
return 0;
}
F - 数据结构实验之二叉树六:哈夫曼编码
Description
字符的编码方式有多种,除了大家熟悉的ASCII编码,哈夫曼编码(Huffman Coding)也是一种编码方式,它是可变字长编码。该方法完全依据字符出现概率来构造出平均长度最短的编码,称之为最优编码。哈夫曼编码常被用于数据文件压缩中,其压缩率通常在20%~90%之间。你的任务是对从键盘输入的一个字符串求出它的ASCII编码长度和哈夫曼编码长度的比值。
Input
Output
Sample
Input
AAAAABCD
THE_CAT_IN_THE_HAT
Output
64 13 4.9
144 51 2.8
Hint
Description
已知一个按先序输入的字符序列,如abd,,eg,,,cf,,,(其中,表示空结点)。请建立该二叉树并按从上到下从左到右的顺序输出该二叉树的所有叶子结点。
Input
Output
Sample
Input
abd,,eg,,,cf,,,
xnl,,i,,u,,
Output
dfg
uli
Hint
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
void qsort(int a[],int low,int high)
{
if(low >= high)
return ;
int i = low,j = high,key = a[low];
while(i < j)
{
while(i < j && a[j] >= key)
j--;
a[i] = a[j];
while(i < j && a[i] <= key)
i++;
a[j] = a[i];
}
a[i] = key;
qsort(a,low,i-1);
qsort(a,i+1,high);
}
int main()
{
char str[1000];
int a[1000],b[1000],c[1000];
while(~scanf("%s",str))
{
int k = 0,e,len,la,lh = 0;
len = strlen(str);
la = 8 * len;
memset(a,0,sizeof(a));
for(int i = 0;i < len;i++)
{
e = str[i] - '0';
a[e]++;
}
for(int i = 0;i < 555;i++)
{
if(a[i] != 0)
{
b[k++] = a[i];
}
}
int j = 0;
qsort(b,0,k-1);
while(k > 1)
{
c[j] = b[0] + b[1];
b[1] = c[j];
j++;
for(int i = 0;i < k;i++)
{
b[i] = b[i+1];
}
k--;
qsort(b,0,k-1);
}
for(int i = 0;i < j;i++)
{
lh += c[i];
}
printf("%d %d %.1lf\n",la,lh,(1.0*la)/lh);
}
return 0;
}
H - 数据结构实验之二叉树八:(中序后序)求二叉树的深度
Description
已知一颗二叉树的中序遍历序列和后序遍历序列,求二叉树的深度。
Input
输入数据有多组,输入T,代表有T组数据。每组数据包括两个长度小于50的字符串,第一个字符串表示二叉树的中序遍历,第二个表示二叉树的后序遍历。
Output
输出二叉树的深度。
Sample
Input
2
dbgeafc
dgebfca
lnixu
linux
Output
4
3
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct TreeNode
{
char data;
TreeNode *lchild;
TreeNode *rchild;
}Treenode;
TreeNode *creattree(int len,char inorder[],char postorder[])
{
int i;
TreeNode *root;
if(!len){
return NULL;
}
root = (TreeNode *)malloc(sizeof(TreeNode));
root->data=postorder[len-1];
for(i=0;i<len;i++){
if(inorder[i]==postorder[len-1]){
break;
}
}
root->lchild=creattree(i,inorder,postorder);
root->rchild=creattree(len-i-1,inorder+i+1,postorder+i);
return root;
}
int getdepth(TreeNode *root)
{
int hl,hr,maxh;
if(root==NULL)
{
return 0;
}
else{
hl = getdepth(root->lchild);
hr = getdepth(root->rchild);
maxh = hl>hr? hl:hr;
return maxh+1;
}
}
int main()
{
int T,len,depth;
char inorder[100],postorder[100];
scanf("%d\n",&T);
while(T--){
TreeNode *root;
scanf("%s%s",inorder,postorder);
len = strlen(inorder);
root = creattree(len,inorder,postorder);
depth = getdepth(root);
printf("%d\n",depth);
}
return 0;
}
I - 二叉树
Description
已知二叉树的一个按前序遍历输入的字符序列,如abc,,de,g,,f,,, (其中,表示空结点)。请建立二叉树,并输出建立二叉树的前序遍历序列、中序遍历序列、后序遍历序列、层次遍历序列、深度、叶子数。
Input
多组测试数据,对于每组测试数据,输入一个长度小于50的按前序遍历输入的字符序列。
Output
对于每组测试数据,第1行输出其前序遍历序列、第2行输出其中序遍历序列、第3行输出其后序遍历序列、第4行输出其深度、第5行输出其叶子数。
Sample
Input
abc,,de,g,,f,,,
Output
abcdegf
cbegdfa
cgefdba
abcdefg
5
3
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char str[100];
int k =0;
typedef struct Treenode
{
char data;
Treenode *lchild;
Treenode *rchild;
}treenode;
treenode *creattree(treenode *T)
{
char ch;
ch = str[k++];
if(ch==','){
T=NULL;
}
else{
T=(treenode *)malloc(sizeof(treenode));
T->data=ch;
T->lchild=creattree(T->lchild);
T->rchild=creattree(T->rchild);
}
return T;
}
void preorder(treenode *T)
{
if(T){
printf("%c",T->data);
preorder(T->lchild);
preorder(T->rchild);
}
}
void inorder(treenode *T)
{
if(T){
inorder(T->lchild);
printf("%c",T->data);
inorder(T->rchild);
}
}
void postorder(treenode *T)
{
if(T){
postorder(T->lchild);
postorder(T->rchild);
printf("%c",T->data);
}
}
void travel(treenode *T)
{
treenode *temp[51];
int rear,front;
rear=front=0;
temp[rear++]=T;
while(rear>front){
if(temp[front]){
printf("%c",temp[front]->data);
temp[rear++]=temp[front]->lchild;
temp[rear++]=temp[front]->rchild;
}
front++;
}
printf("\n");
}
int getdepth(treenode *T)
{
int hl,hr,maxh;
if(!T){
return 0;
}
else{
hl=getdepth(T->lchild);
hr=getdepth(T->rchild);
maxh=hl>hr? hl:hr;
return maxh+1;
}
}
int getleaf(treenode *T)
{
if(!T){
return 0;
}
else if(!T->lchild && !T->rchild){
return 1;
}
else{
return getleaf(T->lchild)+getleaf(T->rchild);
}
}
int main()
{
treenode *T;
while(scanf("%s",str)!=EOF){
T=creattree(T);
preorder(T);
printf("\n");
inorder(T);
printf("\n");
postorder(T);
printf("\n");
travel(T);
printf("%d\n",getdepth(T));
printf("%d\n",getleaf(T));
k = 0;
}
return 0;
}
迷失の搜索树
Description
小璐在机缘巧合之下获得了一个二叉搜索树,这个二叉搜索树恰好有n个节点,每个节点有一个权值,每个节点的权值都在[1,n]这个区间内,并且两两不相同,真是优美的性质啊
但是命运的不公又让她失去了这个二叉搜索树
幸运的是,她还记得自己丢失的二叉搜索树的前序遍历序列。
在丢了二叉搜索树之后,小璐无比想念她的这个树的后序遍历
那么问题来了,聪明的你在知道这个二叉搜索树的前序遍历的序列的情况下,能帮她找到这个二叉搜索树的后序遍历嘛?
Input
多组输入,以文件结尾
每组数据第一行为一个整数n,代表这个二叉搜索树的节点个数(1<=n<=100)
接下来一行n个整数,代表这个二叉搜索树的前序遍历序列
Output
输出n个整数
表示这个二叉树的后序遍历序列
Sample
Input
5
4 2 1 3 5
Output
1 3 2 5 4
Hint
二叉查找树是一棵空树,或者是具有下列性质的二叉树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值
它的左、右子树也分别为二叉排序树
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Treenode
{
int data;
Treenode *lchild;
Treenode *rchild;
}treenode;
treenode *creattree(treenode *T,int x)
{
if(!T){
T=(treenode *)malloc(sizeof(treenode));
T->data=x;
T->lchild=T->rchild=NULL;
}
else
{
if(x>T->data){
T->rchild=creattree(T->rchild,x);
}
else{
T->lchild=creattree(T->lchild,x);
}
}
return T;
}
void postorder(treenode *T)
{
if(T){
postorder(T->lchild);
postorder(T->rchild);
printf("%d ",T->data);
}
}
int main()
{
treenode *T;
int n,x;
while(scanf("%d",&n)!=EOF){
treenode *T;
T=(treenode *)malloc(sizeof(treenode));
T=NULL;
for(int i=0;i<n;i++){
scanf("%d",&x);
T=creattree(T,x);
}
postorder(T);
printf("\n");
}
return 0;
}
巨斧砍大树
Description
阿福最近练就了一个新的招式:巨斧砍大树。这个招式可以砍掉一颗二叉搜索树的某个子树。现在,阿福面前有一颗 nn 个结点的二叉搜索树,他要使用 mm 次招式,于是他想询问你每次使用「巨斧砍大树」后二叉搜索树会被砍成什么样子。
二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。
Input
第一行输入 22 个整数 nn, mm (1 \leqslant n, m \leqslant 10)(1⩽n,m⩽10)。表示二叉搜索树的结点个数和招式使用次数。
第二行输入 nn 个空格隔开的整数 vv (1 \leqslant v \leqslant 10)(1⩽v⩽10),表示二叉搜索树是以此序列顺序插入生成的二叉树(保证互不相同)。
接下来输入 mm 行,每行一个整数 ww (1 \leqslant w \leqslant 10)(1⩽w⩽10),表示阿福要砍掉结点上数值为 ww 的子树(保证 ww 是初始二叉树上存在的数值)。
Output
对于每次砍树,如果成功砍掉子树,则先输出一行 Cut x
,其中 xx 为被砍掉子树的根节点上的数值。如果要砍掉的结点在之前已被砍掉,则输出一行 Already cut x
,xx 的含义同上。
随后输出一行,表示此次砍树结束后当前二叉树的中序遍历结果,以空格分隔(行末没有多余空格,如果整颗二叉树已为空,则输出一行空行)。
Sample
Input
5 5
1 3 2 4 5
5
2
3
4
1
Output
Cut 5
1 2 3 4
Cut 2
1 3 4
Cut 3
1
Already cut 4
1
Cut 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct Treenode
{
int data;
Treenode *lchild;
Treenode *rchild;
}treenode;
treenode *creattree(treenode *T,int x)
{
if(T==NULL){
T=(treenode *)malloc(sizeof(treenode));
T->data=x;
T->lchild=T->rchild=NULL;
return T;
}
else{
if(x>T->data){
T->rchild=creattree(T->rchild,x);
}
else{
T->lchild=creattree(T->lchild,x);
}
}
return T;
}
void inorder(treenode *T)
{
if(T){
inorder(T->lchild);
printf("%d ",T->data);
inorder(T->rchild);
}
}
treenode *deltree(treenode *T,int x)
{
if(T){
if(x>T->data){
T->rchild=deltree(T->rchild,x);
}
else if(x<T->data){
T->lchild=deltree(T->lchild,x);
}
else if(x==T->data)
{
T = NULL;
printf("Cut %d\n",x);
return T;
}
}
else{
printf("Already cut %d\n",x);
return T;
}
return T;
}
int main()
{
int n,m,t,a[11];
treenode *T;
T=(treenode *)malloc(sizeof(treenode));
T=NULL;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++){
T=creattree(T,a[i]);
}
for(int i=0;i<m;i++){
scanf("%d",&t);
T=deltree(T,t);
inorder(T);
printf("\n");
}
return 0;
}
二叉排序树
Description
二叉排序树的定义是:或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。 今天我们要判断两序列是否为同一二叉排序树
Input
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉排序树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉排序树。(数据保证不会有空树)
Output
Sample
Input
2 123456789 987654321 432156789 0
Output
NO NO
Hint
就是判断两个二叉搜索树是不是为一个树
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Treenode
{
int data;
Treenode *lchild;
Treenode *rchild;
}treenode;
treenode *creattree(treenode *root,char x)
{
if(root==NULL){
root=(treenode *)malloc(sizeof(treenode));
root->data=x;
root->lchild=root->rchild=NULL;
}
else{
if(x>root->data){
root->rchild=creattree(root->rchild,x);
}
else{
root->lchild=creattree(root->lchild,x);
}
}
return root;
}
int judgetree(treenode *root1,treenode *root2)
{
if(root1==NULL || root2==NULL)
{
return 0;
}
if(root1 && root2)
{
if(root1->data!=root2->data)
return 0;
else
{
return judgetree(root1->lchild,root2->lchild)+judgetree(root1->rchild,root2->rchild)+1;
}
}
}
int main()
{
int n,len,num;
char str1[21],str2[21];
while(scanf("%d",&n) != EOF)
{
if(n==0){
break;
}
treenode *root1;
root1=(treenode *)malloc(sizeof(treenode));
root1=NULL;
scanf("%s",str1);
len = strlen(str1);
for(int i=0;i<len;i++){
root1=creattree(root1,str1[i]);
}
for(int i=0;i<n;i++){
treenode *root2;
root2=(treenode *)malloc(sizeof(treenode));
root2=NULL;
scanf("%s",str2);
for(int i= 0;i<len;i++){
root2=creattree(root2,str2[i]);
}
num=judgetree(root1,root2);
if(num==len){
printf("YES\n");
}
else{
printf("NO\n");
}
}
}
return 0;
}