二叉树的构建和遍历(例题)

21 篇文章 0 订阅
21 篇文章 0 订阅

直接进入正题:
比如有些题目给你一颗二叉树的前序遍历和中序遍历,然后让你求层序遍历或者后序遍历。
这种题目的基本思路有两个:

1.给定的序列是以字符串的形式:
比如后序序列:BDCA,中序序列:BADC ,然后让你求先序序列。
这类问题实际上已经为你构建好了数,只需要利用字符串的截取操作(sunstr)以及dfs / bfs解决:

参考文章<==戳这

#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
==>要注意在树的每一部分,任何类型的遍历序列长度都是一样的
void dfs(string mid,string post){
	if(mid.empty()) return;				==>序列为空是递归结束的标志
	else{
		char root=post[post.size()-1];	==>找到该部分的“主根”
		int pos=mid.find(root);			==>“主根”在中序序列中的位置
		printf("%c",root);										 ==>“根”
		dfs(mid.substr(0,pos),post.substr(0,pos));				 ==>“左”
		dfs(mid.substr(pos+1),post.substr(pos,post.size()-k-1)); ==>“右”
	}
}
int main(){
	string mid,post;  ==>中序序列,后序序列
	cin>>mid>>post;
	dfs(mid,post);
}

2.给定的序列是整形,需要数组存储:

后序序列:2 3 1 5 7 6 4
中序序列:1 2 3 4 5 6 7
然后让你求前序序列。这类问题需要构建这颗二叉树,然后再根据题意运用 dfs / bfs 解决。
比如这道题:求层序序列 就运用了bfs

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
int post[50],inor[50],n;			//后序序列,中序序列,个数
struct node{						
	int date;		//结点数据域(结点标号)
	node* lchild;	//左子树
	node* rchild;	//右子树
};
node* tree(int postl,int postr,int inl,int inr){ //后序序列的左下标,右下标,中序序列的左下标,右下标
	if(postl>postr) return NULL;	//如果后序序列小于 1 的时候,到达递归边界 
	node* root=new node;			//创建一个新的结点用来存放根节点 
	root->date=post[postr];			//后序序列的最后一个元素是根 
	int k;							//找出根节点在中序遍历中的位置并记录
	for(k=inl;k<=inr;k++){
		if(post[postr]==inor[k]){
			break;
		}
	}
	int numleft=k-inl;          	//左子树的结点个数
	//二叉树结点的建立是从左到右的 
	//更改下标继续建树(仔细)								
	root->lchild = tree(postl,postl+numleft-1,inl,k-1);	
	root->rchild = tree(postl+numleft,postr-1,k+1,inr); 
	return root;
}
int num=0;
void bfs(node* root){	//bfs板子,因为层序遍历本质上就是广搜
	queue<node*> q;		//注意队列元素类型是 node*
	q.push(root);
	while(!q.empty()){
		node* top=q.front();
		q.pop();
		printf("%d",top->date);	//依次把根节点输出就行了
		num++;
		if(num<n) putchar(' ');	//空格的处理
		if(top->lchild!=NULL) q.push(top->lchild);
		if(top->rchild!=NULL) q.push(top->rchild); 
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&post[i]);
	for(int i=1;i<=n;i++) scanf("%d",&inor[i]);
	node* root=tree(1,n,1,n);		//建立以root为根的 node* 类型的一颗二叉树
	bfs(root);						//bfs层序遍历这颗树
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值