L2-011 玩转二叉树 (25 分) 三种解法
Published on 2022-11-17 23:03 in 暂未分类 with 林动

L2-011 玩转二叉树 (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

    所谓的反转只需要在层次遍历是先将右孩子入队即可

    数组模拟树结构(推荐)
    #include <bits/stdc++.h>
    using namespace std;
    const int N=50;
    map<int,int>zon;
    int a[N];
    int w[N],l[N],r[N],cnt=1;//根节点的地址为1 
    void bfs()
    {
    	queue<int> q;
    	q.push(1);
    	cout<<w[1];
    	while(!q.empty()){
    		int t=q.front();q.pop();
    		if(t!=1)cout<<" "<<w[t];
    		if(r[t])q.push(r[t]);
    		if(l[t])q.push(l[t]);
    	}
    }
    int main()
    {
    	int n;cin>>n;
    	for(int i=0;i<n;++i){
    		int x;cin>>x;
    		zon[x]=i;
    	}
    	for(int i=0;i<n;++i)cin>>a[i];
    	for(int i=0;i<n;++i)
    	{
    		int x=a[i];
    		int dx=zon[x];
    		if(cnt==1){//如果当前树为空 
    			w[cnt++]=x;
    		}else {
    			int t=1;
    			while(1){//找到当前值应该插入到树的位置 
    				int dy=zon[w[t]];
    				if(dx<dy){
    					if(l[t]==0){
    						l[t]=cnt;
    						w[cnt++]=x;
    						break;
    					}else t=l[t];
    				}else {
    					if(r[t]==0){
    						r[t]=cnt;
    						w[cnt++]=x;
    						break;
    					}else t=r[t];
    				}
    			}
    		}
    	}
    	bfs();
    	return 0;
    } 
    
    只用一个数组,用下标作左右孩子

    这里直接用数组下标来做左右孩子了,理论上2^30肯定是不行的,但是题目数据甚至只到 10 ^6,所以卡一下bug了

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1000005;
    map<int,int> zon;
    int a[50];
    int w[N];
    void bfs(){
    	queue<int> q;
    	q.push(0);
    	cout<<w[0];
    	while(!q.empty())
    	{
    		int t=q.front();q.pop();
    		if(t!=0)cout<<" "<<w[t];
    		int l=t*2+1;
    		int r=t*2+2;
    		if(w[r]!=-1)q.push(r);
    		if(w[l]!=-1)q.push(l);
    	}
    } 
    int main()
    {
    	int n;cin>>n;
    	for(int i=0;i<n;++i){
    		int x;cin>>x;
    		zon[x]=i;
    	}
    	for(int i=0;i<n;++i)cin>>a[i];
    	memset(w,-1,sizeof w);
    	for(int i=0;i<n;++i)
    	{
    		int x=a[i];
    		int dx=zon[x];
    		if(w[0]==-1){
    			w[0]=x;
    		}else {
    			int t=0;
    			while(1){
    				int dy=zon[w[t]];
    				int l=t*2+1;
    				int r=t*2+2;
    				if(dx<dy){
    					if(w[l]==-1){
    						w[l]=x;
    						break;
    					}else t=l;
    				}else {
    					if(w[r]==-1){
    						w[r]=x;
    						break;
    					}else t=r;
    				}
    			}
    		}
    	}
    	bfs();
    	return 0;
    }
    
    链式结构
    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n,qian[50];
    class  node
    {
    	public:
    	node *l,*r;
    	int w;
    }* h;
    map<int,int> zon;
    
    node * dfs(int qianl,int qianr,int zonl,int zonr)
    {
    	if(qianl>qianr)return NULL;
    	node *root=new node();
    	root->w=qian[qianl];
    	int k=zon[qian[qianl]]-zonl;//左子树的元素个数 
    	root->l=dfs(qianl+1,qianl+k,zonl,zon[qian[qianl]]-1);
    	root->r=dfs(qianl+k+1,qianr,zon[qian[qianl]]+1,zonr);
    	return root;
    }
    
    void cen(node * h)
    {
    	queue<node *> q;
    	q.push(h);
    	cout<<h->w;
    	while(!q.empty())
    	{
    		node * t=q.front();q.pop();
    		if(t->r!=NULL)q.push(t->r);
    		if(t->l!=NULL)q.push(t->l);
    		if(t!=h)cout<<" "<<t->w;
    	}
    }
    
    int main()
    {
    	cin>>n;
    	for(int i=0;i<n;++i)
    	{
    		int x;cin>>x;
    		zon[x]=i;
    	}
    	for(int i=0;i<n;++i)cin>>qian[i];
    	
    	h=dfs(0,n-1,0,n-1);
    	cen(h);
    	
    	return 0;
    }
    
    posted @   林动  阅读(12)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
    · 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
    · Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
    · 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
    · AI技术革命,工作效率10个最佳AI工具
    点击右上角即可分享
    微信分享提示