版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
玩转二叉树(25 分)
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N
(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:
7
1 2 3 4 5 6 7
4 1 3 2 6 5 7
输出样例:
4 6 1 7 5 3 2
不要跟着题目走,只需要达到输出目的就可以了,开始竟然真的递归的交换了左右子树,mmp
//方法一 改变层次遍历的顺序,即改成 根-右孩子-左孩子
#include<cstdio>
#include<queue>
using namespace std;
int ans[100000];
int k=0;
template<class T>
struct node
{
T data;
node *left,*right;
};
template<class T>
node<T>* makelinked(const T *pre,const T *in,int n)
{
if(n<=0)
return NULL;
node<T> *t=new node<T>;
int i=0;
t->data=*pre;
for(;i<n;i++)
if(*pre==in[i])
break;
t->left=makelinked(pre+1,in, i);
t->right=makelinked(pre+1+i,in+1+i,n-i-1);
return t;
}
template<class T>
void mirror_level(node<T> *t) //
{
queue<node<T> *> q;
q.push(t);
node<T> *p;
while(!q.empty())
{
p=q.front();
ans[k++]=p->data;
q.pop();
if(p->right)
q.push(p->right);
if(p->left)
q.push(p->left);
}
}
int main()
{
int In[35],pre[35];
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>In[i];
for(int i=0;i<n;i++)
cin>>pre[i];
node<int> *root=makelinked(pre,In,n);
mirror_level(root);
for(int i=0;i<n;i++)
if(i<n-1)
cout<<ans[i]<<' ';
else
cout<<ans[i]<<endl;
return 0;
}
//按题目来,另写一个函数递归的交换左右孩子
#include<iostream>
#include<queue>
#include<cstdlib>
using namespace std;
int ans[35];
int c=0;
template<class T>
struct BTNode
{
T data;
BTNode *left, *right;
BTNode(const T& d=T(),BTNode *l=NULL,BTNode *r=NULL):data(d),left(l),right(r){}
};
template<class T>
BTNode<T>* GetBTNode(const T& d,BTNode<T>* l=NULL,BTNode<T> *r=NULL)
{
BTNode<T> *t;
t=new BTNode<T>(d,l,r);
if(t==NULL)
{
cout<<"alocate memory failure\n";
exit(1);
}
return t;
}
template<class T>
BTNode<T>*MakeLinked(const T* pL,const T* iL, int size)
{
if(size<=0)
return NULL;
BTNode<T> *t,*left,*right;
const T *rL;
int k;
for(rL=iL;rL<iL+size;rL++)
if(*rL==*pL)
break;
k=rL-iL;
left=MakeLinked(pL+1,iL,k);
right=MakeLinked(pL+k+1,iL+k+1,size-k-1);
t=GetBTNode(*pL,left,right);
return (t);
}
template<class T>
void Level(const BTNode<T> *t)
{
if(t==NULL)
return ;
queue<const BTNode<T> *> Q;
Q.push(t);
while(!Q.empty())
{
t=Q.front();
Q.pop();
ans[c++]=t->data;
if(t->left)
Q.push(t->left);
if(t->right)
Q.push(t->right);
}
}
template<class T>
void mirror_image(BTNode<T>* t) //递归的交换左右孩子
{
if(t==NULL)
return ;
swap(t->left,t->right);
mirror_image(t->left);
mirror_image(t->right);
}
int main()
{
int In[35],pre[35];
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>In[i];
for(int i=0;i<n;i++)
cin>>pre[i];
BTNode<int> *root=MakeLinked(pre,In,n);
mirror_image(root);
Level(root);
for(int i=0;i<n;i++)
{
cout<<ans[i];
if(i<n-1)
cout<<' ';
}
return 0;
}
//方法三 直接在构建二叉树时就交换左右子树
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int ans[100000];
int k=0;
template<class T>
struct node
{
T data;
node *left,*right;
};
template<class T>
node<T>* makelinked(const T *pre,const T *in,int n)//构建二叉树时就将左右孩子交换,即原本的左子树赋给右子树,原本的右子树赋给左子树达到翻转效果
{
if(n<=0)
return NULL;
node<T> *t=new node<T>;
int i=0;
t->data=*pre;
for(;i<n;i++)
if(*pre==in[i])
break;
t->left=makelinked(pre+1+i,in+1+i,n-i-1);//注意
t->right=makelinked(pre+1,in, i);//注意
return t;
}
template<class T>
void level(node<T> *t)
{
queue<node<T> *> q;
q.push(t);
node<T> *p;
while(!q.empty())
{
p=q.front();
ans[k++]=p->data;
q.pop();
if(p->left)
q.push(p->left);
if(p->right)
q.push(p->right);
}
}
int main()
{
int In[35],pre[35];
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>In[i];
for(int i=0;i<n;i++)
cin>>pre[i];
node<int> *root=makelinked(pre,In,n);
level(root);
for(int i=0;i<n;i++)
if(i<n-1)
cout<<ans[i]<<' ';
else
cout<<ans[i]<<endl;
return 0;
}