CCCC团体天梯赛-树的遍历 + 玩转二叉树

来源:互联网 发布:知耻而后勇 编辑:程序博客网 时间:2024/04/29 11:13

这里直接两个一起写了,因为这两个题目的类型是一模一样的。玩转二叉树那我一开始想法有点错误,因为我并不知道中序遍历前序遍历其实是怎么得到的,然后推出了一个没有规律的式子。。。

先看树的遍历

L2-006. 树的遍历

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

输入格式:

输入第一行给出一个正整数N(<=30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。

输出格式:

在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

输入样例:
72 3 1 5 7 6 41 2 3 4 5 6 7
输出样例:
4 1 6 3 5 7 2

这题目很简单,并不需要什么模板,自己做就能做出来,我是用的链表去建的树,层次遍历那自己想想,我是用了两个指针数组,然后就ac了

代码如下:

#include<stdio.h>#include<stdlib.h>#include<string.h>int back[1024]={0};int mid[1024]={0};struct Tree{int s;struct Tree *left;struct Tree *right;};void build(int bs,int be,int ms,int me,struct Tree *p){int left_number,right_number; int i;int root=back[be];p->s=root;for(i=ms;mid[i]!=root;i++);left_number=i-ms;right_number=be-bs-left_number;if(left_number)//如果左子树存在{p->left=(struct Tree*)malloc(sizeof(struct Tree));build(bs, bs+left_number-1, ms, i-1,p->left);}elsep->left=NULL;if(right_number)//如果右子树存在{p->right=(struct Tree*)malloc(sizeof(struct Tree));build(bs+left_number, be-1, i+1, me, p->right);}elsep->right=NULL;}int main(){int n,i,k,t;struct Tree *root,*a[320],*b[320];scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&back[i]);for(i=1;i<=n;i++)scanf("%d",&mid[i]);root=(struct Tree*)malloc(sizeof(struct Tree));//先动态创建出根结点的地址build(1,n,1,n,root);//建树k=0;if(root->left!=NULL)a[k++]=root->left;if(root->right!=NULL)a[k++]=root->right;printf("%d",root->s); //先输出根结点的数字while(k)//如果a数组不为空{t=0;for(i=0;i<k;i++){printf(" %d",a[i]->s);//这步是必须的if(a[i]->left!=NULL||a[i]->right!=NULL)//如果这个结点有子树的话,加进临时数组b中{if(a[i]->left!=NULL){b[t++]=a[i]->left;}if(a[i]->right!=NULL){b[t++]=a[i]->right;}}}for(i=0;i<t;i++){a[i]=b[i];//把b的地址全交给a以进行下一次的循环}k=t;}putchar(10);} 

接下来就是玩转二叉树,可以说是一模一样的

代码如下:

#include<stdio.h>#include<stdlib.h>#include<string.h>int front[1024]={0};int mid[1024]={0};struct Tree{int s;struct Tree *left;struct Tree *right;};void build(int fs,int fe,int ms,int me,struct Tree *p){int left_number,right_number; int i;int root=front[fs];p->s=root;//根值 for(i=ms;mid[i]!=root;i++);left_number=i-ms;//得到左子树的节点个数 right_number=me-i;//得到右子树的节点个数 if(left_number){p->left=(struct Tree*)malloc(sizeof(struct Tree));build(fs+1, fs+left_number, ms, i-1, p->left);//左子树递归 }elsep->left=NULL;if(right_number){p->right=(struct Tree*)malloc(sizeof(struct Tree));build(fs+left_number+1, fe, i+1, me, p->right);//右子树递归}elsep->right=NULL;//如果不存在则为空 }int main(){int n,i,k,t;struct Tree *root,*a[320],*b[320];scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&mid[i]);for(i=1;i<=n;i++)scanf("%d",&front[i]);root=(struct Tree*)malloc(sizeof(struct Tree));build(1,n,1,n,root);k=0;if(root->right!=NULL)a[k++]=root->right;if(root->left!=NULL)a[k++]=root->left;printf("%d",root->s); while(k)//层次遍历输出 {t=0;for(i=0;i<k;i++){printf(" %d",a[i]->s);if(a[i]->left!=NULL||a[i]->right!=NULL){if(a[i]->right!=NULL){b[t++]=a[i]->right;}if(a[i]->left!=NULL){b[t++]=a[i]->left;}}}for(i=0;i<t;i++){a[i]=b[i];}k=t;}putchar(10);} 


0 0
原创粉丝点击