PTAL2-006. 树的遍历(后序、中序确定一棵二叉树)

思路: 

后序遍历是左节点->右节点->父节点,所以最后一个元素是二叉树的根

再到中序遍历中找到这个元素,然后中序遍历这个元素左边的数属于左子树的,右边的数属于右子树的。

用一个数组来存取二叉树,最后遍历输出,可以用for循环也可以用bfs输出,两种下面都有

看代码~~

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int s1[10000], s2[10000], s3[10000];
int n;
//p1 p2 q1 q2 分别表示两种遍历的起始位置(p表示中序,q表示后序)
//index 表示当前根结点在二叉树中的位置(层次遍历)
void f(int p1, int p2, int q1, int q2, int index)
{
	if (p1 > p2 || q1 > q2)
		return;
	int i = p1;
	while (s1[i] != s2[q2])//在中序遍历中找后序遍历的最后一个元素
	{
		i++;
	}
	s3[index] = s1[i];
	//left
	f(p1, i - 1, q1, q1 + i - p1 - 1, 2 * index + 1);
	//关于上面这里,i-p1表示中序元素左边有多少个元素,而q1+i-p1-1表示在后序遍历中属于中序元素左边的数的最后一个数的索引位置
	//right
	f(i + 1, p2, q1 + i - p1, q2 - 1, 2 * index + 2);//q1 + i - p1属于右边的第一个索引位置
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> s2[i];//后序遍历的数组
	}
	for (int i = 0; i < n; i++)
	{
		cin >> s1[i];//中序遍历的数组
	}
	memset(s3, 0, sizeof(s3));//初始化层次遍历时的二叉树数组
	f(0, n - 1, 0, n - 1, 0);
	int cnt = 0;//用于计数
	for (int i = 0; i <= 100000; i++)
	{
		if (cnt == n)
		{
			break;
		}
		if (s3[i] != 0)
		{
			cnt++;//
			
			cout << s3[i];
			if (cnt != n)//这里用控制空格,否则会格式输出错误
			{
				cout << " ";
			}
			
		}
	}
	system("pause");
	return 0;
}

尝试用一下层次遍历进行输出~

 

#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
int s1[10000], s2[10000], s3[10000];
int n;
//p1 p2 q1 q2 分别表示两种遍历的起始位置(p表示中序,q表示后序)
//index 表示当前根结点在二叉树中的位置(层次遍历)
void f(int p1, int p2, int q1, int q2, int index)
{
	if (p1 > p2 || q1 > q2)
		return;
	int i = p1;
	while (s1[i] != s2[q2])//在中序遍历中找后序遍历的最后一个元素
	{
		i++;
	}
	s3[index] = s1[i];
	//left
	f(p1, i - 1, q1, q1 + i - p1 - 1, 2 * index + 1);
	//关于上面这里,i-p1表示中序元素左边有多少个元素,而q1+i-p1-1表示在后序遍历中属于中序元素左边的数的最后一个数的索引位置
	//right
	f(i + 1, p2, q1 + i - p1, q2 - 1, 2 * index + 2);//q1 + i - p1属于右边的第一个索引位置
}
void print(int s)//利用bfs进行层次输出,减少时间复杂度
{
	int count = 0;
	queue<int> qu;
	qu.push(s);//进队列
	while (!qu.empty()&&count<=n)
	{
		int a = qu.front();
		qu.pop();
		
		if (count<=n&&s3[a]!=0)//不为0的数才算
		{
			cout << s3[a];
			count++;//计数
			if (count!= n)//注意格式输出,最后一个没有空格
			{
				cout << " ";
			}
			qu.push(2 * a + 1);//进队列
			qu.push(2 * a + 2);
		}

	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> s2[i];//后序遍历的数组
	}
	for (int i = 0; i < n; i++)
	{
		cin >> s1[i];//中序遍历的数组
	}
	memset(s3, 0, sizeof(s3));//初始化层次遍历时的二叉树数组
	f(0, n - 1, 0, n - 1, 0);
	
	print(0);
	
	system("pause");
	return 0;
}

求点赞哈哈~~(粉色才是男人的浪漫)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值