玩转二叉树

题目链接

二叉树综合大礼包

  1. 遍历顺序
  2. 构造二叉树
  3. 翻转二叉树
  4. 层序遍历二叉树

一, 遍历顺序

前序遍历:中前后

中序遍历:前中后

后序遍历:前中后

void dfs(node* p)
{
    //前序遍历 
	if(p==NULL) return ;
	cout<<p->val<<' ';
	dfs(p->left);
	dfs(p->right);
	return ;
	//中序遍历 
	if(p==NULL) return ;
	dfs(p->left);
	cout<<p->val<<' ';
	dfs(p->right);
	return;
}

二,构造二叉树

        前序或后序加上中序遍历就可以构造一棵二叉树,这里以前序中序为例,前序遍历的第一个一定是相对与其他元素的根节点,而中序遍历中以此元素为界,分开左右子树,我们对一个前序中序数组可以分出左右子树的前序中序数组,进行递归即可构造,注意剩余1个元素时就是叶子节点代码如下

node* build(int b1,int b2,int m1,int m2)
{
	if(b1>b2)
	{
		return NULL;
	}
	node* s=new node;
	s->val=bef[b1];
	if(b1==b2)
	{
		s->left=NULL;
		s->right=NULL;
		return s;
	}
	int sign=-1;
	for(int i=m1;i<=m2;i++)
	{
		if(mid[i]==bef[b1])
		{
			sign=i;
			break;
		}
	}
	int counts=sign-m1;
	s->left=build(b1+1,b1+counts,m1,sign-1);
	s->right=build(b1+counts+1,b2,sign+1,m2);
	return s;
}

三,翻转二叉树

每个左子树与右子树的地址交换就得到了镜像翻转的二叉树

四,层序遍历

与前序中序不同,层序遍历更类似于bfs

我们使用一个队列进行记录各个节点的地址,每次往队尾添加队头的左右子树的地址,然后更新队头,若为null不记录,当l不小于r时退出,我们就得到了一个层序遍历的数组

lis[l]=tree;
	r=1;	
	while(l<r)
	{
		if(lis[l]->left!=NULL) lis[r++]=lis[l]->left;
		if(lis[l]->right!=NULL) lis[r++]=lis[l]->right;
		l++;
	}
	for(int i=0;lis[i]!=NULL;i++)
	{
		if(i) cout<<' ';
		cout<<lis[i]->val;
	}

完整的代码

#include <bits/stdc++.h>
using namespace std;
typedef struct node
{
	int val;
	node* left;
	node* right;
}node;
node*lis[100]={0};
int l=0,r=0;
vector<int> bef;
vector<int> mid;
node* build(int b1,int b2,int m1,int m2)
{
	if(b1>b2)
	{
		return NULL;
	}
	node* s=new node;
	s->val=bef[b1];
	if(b1==b2)
	{
		s->left=NULL;
		s->right=NULL;
		return s;
	}
	int sign=-1;
	for(int i=m1;i<=m2;i++)
	{
		if(mid[i]==bef[b1])
		{
			sign=i;
			break;
		}
	}
	int counts=sign-m1;
	s->left=build(b1+1,b1+counts,m1,sign-1);
	s->right=build(b1+counts+1,b2,sign+1,m2);
	return s;
}
void swaps(node* p)
{
	if(p==NULL) return ;
	node* tem=p->left;
	p->left=p->right;
	p->right=tem;
	swaps(p->left);
	swaps(p->right);
	return ;
}
/*void dfs(node* p)
{
    前序遍历 
	if(p==NULL) return ;
	cout<<p->val<<' ';
	dfs(p->left);
	dfs(p->right);
	return ;
	中序遍历 
	if(p==NULL) return ;
	dfs(p->left);
	cout<<p->val<<' ';
	dfs(p->right);
	return;
}*/
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n;cin>>n; 
	for(int i=0;i<n;i++)
	{
		int tem;
		cin>>tem;
		mid.push_back(tem);
	}
	for(int i=0;i<n;i++)
	{
		int tem;
		cin>>tem;
		bef.push_back(tem);
	}
	node* tree=build(0,bef.size()-1,0,mid.size()-1);
	//dfs(tree);
	swaps(tree);
	lis[l]=tree;
	r=1;	
	while(l<r)
	{
		if(lis[l]->left!=NULL) lis[r++]=lis[l]->left;
		if(lis[l]->right!=NULL) lis[r++]=lis[l]->right;
		l++;
	}
	for(int i=0;lis[i]!=NULL;i++)
	{
		if(i) cout<<' ';
		cout<<lis[i]->val;
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值