中序 + 后序 序列建立二叉树

本文介绍了一道关于数据结构的题目,涉及如何根据二叉树的中序遍历和后序遍历序列构建二叉树,并输出其左右视图。通过AC代码展示了如何实现这一过程,包括利用递归构建二叉树和层次遍历获取左右视图的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉树的建立

哈哈, 原本是数据结构的一道题,期末考试写出来了,到现在写题又给忘了,那咱们就来学一学吧!
7-11 浪漫侧影 (25 分)

“侧影”就是从左侧或者右侧去观察物体所看到的内容。例如上图中男生的侧影是从他右侧看过去的样子,叫“右视图”;女生的侧影是从她左侧看过去的样子,叫“左视图”。

520 这个日子还在打比赛的你,也就抱着一棵二叉树左看看右看看了……

我们将二叉树的“侧影”定义为从一侧能看到的所有结点从上到下形成的序列。例如下图这棵二叉树,其右视图就是 { 1, 2, 3, 4, 5 },左视图就是 { 1, 6, 7, 8, 5 }。
于是让我们首先通过一棵二叉树的中序遍历序列和后序遍历序列构建出一棵树,然后你要输出这棵树的左视图和右视图。

输入格式:
输入第一行给出一个正整数 N (≤20),为树中的结点个数。随后在两行中先后给出树的中序遍历和后序遍历序列。树中所有键值都不相同,其数值大小无关紧要,都不超过 int 的范围。

输出格式:
第一行输出右视图,第二行输出左视图,格式如样例所示。

输入样例:
8
6 8 7 4 5 1 3 2
8 5 4 7 6 3 2 1
输出样例:
R: 1 2 3 4 5
L: 1 6 7 8 5

AC代码, 详情见注释

#include "bits/stdc++.h"
using namespace std;
vector<int> z, h;

struct node{
	node *lchild;
	node *rchild;
	int val;
};
int p; // 指出当前所在的后序遍历位置 
node* build(node *root, int s, int e){
	if(s > e) return NULL;
	root = new node;
	root->lchild = root->rchild = NULL;
	root->val = h[p];
	int t;
	for(int i = s; i <= e; i++){ // 找到当前h[p] 在z中的位置
		if(z[i] == h[p]){
			t = i;
			break;
		}
	}
	p--; // 建完往下走
	if(s == e) return root;
	
	root->rchild = build(root, t + 1, e);// 递归建树
	root->lchild = build(root, s, t - 1); 
	
	return root;
}

void f(node *root){
	if(root == NULL) return;
	cout<<root->val<<endl;
	if(root->lchild != NULL) f(root->lchild);
	
	if(root->rchild != NULL) f(root->rchild);
	
}

int main(){
	
	int n;
	cin>>n;
	for(int i = 0; i < n; i++) {
		int d;
		cin>>d;
		z.push_back(d);
	}
	for(int i = 0; i < n; i++) {
		int d;
		cin>>d;
		h.push_back(d);
	}
	p = n - 1;
	node* root = NULL;
	root = build(root, 0, n - 1);
	// 左右视图用了一个二叉树的层序遍历分别取第一个和最后一个就是左视图和右视图
	queue<node*> q;
	q.push(root);
	vector<int> L, R;
	while(q.size()){  
		int d = q.size();
		vector<int> v; 
		for(int i = 0; i < d; i++){
			node* t = q.front();q.pop();
			v.push_back(t->val);
			if(t->lchild) q.push(t->lchild);
			if(t->rchild) q.push(t->rchild);
		}
		L.push_back(v[0]);
		R.push_back(v.back());
	}
    
	cout<<"R: ";
	for(int i = 0; i < R.size(); i++){
        if(i == 0)cout<<R[i];
		else cout<<" "<<R[i];
	}
    cout<<endl;
	cout<<"L: ";
	for(int i = 0; i < L.size(); i++){
		if(i == 0)cout<<L[0];
        else cout<<" "<<L[i];
	}
	
	return 0;
}
/*
8
6 8 7 4 5 1 3 2
8 5 4 7 6 3 2 1
*/
### 构造二叉树的Python实现 通过中后序遍历序列构造二叉树的关键在于理解这两种遍历方式的特点。后序遍历中的最后一个元素总是当前子树的根节点,在中遍历中该位置可以用来划分左右子树。 #### Python代码实现 下面是一个基于上述原理的具体算法实现: ```python # 定义二叉树结点类 class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(inorder, postorder): if not postorder or not inorder: return None # 创建根节点,后序遍历最后一个是根节点 root_val = postorder[-1] root = TreeNode(root_val) # 找到根节点在中的位置 mid_index = inorder.index(root_val) # 利用切片操作分别获取左子树右子树对应的inorderpostorder列表, # 并递归调用buildTree函数来创建左右子树。 # 左子树的中遍历 left_inorder = inorder[:mid_index] # 右子树的中遍历 right_inorder = inorder[mid_index + 1:] # 前面已经把root弹出了所以这里不需要再减去1 total_length_left = len(left_inorder) # 左子树的后续遍历 left_postorder = postorder[:total_length_left] # 右子树的后续遍历 right_postorder = postorder[total_length_left : -1] # 对于每个部分都可以看作一个新的问题实例,因此可以直接递归求解 root.left = buildTree(left_inorder, left_postorder) root.right = buildTree(right_inorder, right_postorder) return root ``` 此段代码定义了一个`TreeNode`类用于表示二叉树节点,并实现了`buildTree()`函数,它接收两个参数——中遍历列表`inorder`以及后序遍历列表`postorder`,最终返回重建后的二叉树对象[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值