PATA 1020二叉树的恢复与遍历

题目描述:

Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order traversal sequence of the corresponding binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the level order traversal sequence of the corresponding binary tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

题目的意思就是,给出一个二叉树的后序和中序的遍历序列,给出它的层次遍历结果。

思路:题目的关键是对二叉树的恢复。给出后序序列可以确定出根节点,之后在中序序列中找到相应的根节点就可以划分出左子树和右子树,对二叉树进行递归创建。递归函数在编写的时候,一定要先找好递归边界和递归表达式。

遇到的问题:在编写代码的过程中,遇到的最大的问题是参数值的传递,左子树右子树划分的边界值没有找对,正确的划分如下图所示:

 还有一个很愚蠢的错误就是,在对二叉树进行层次遍历的时候,我!居!然!忘!记!了!对左右子树是否为空的判断,就是每次考完试总是要把脑子丢在考场上几天。

代码如下:

// PATA1020.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "iostream"
#include "algorithm"
#include "queue"
using namespace std;
struct node
{
	int data;
	node* lchild;
	node* rchild;
};
int postdata[50], indata[50];
node* Create(int pl,int pr,int il,int ir)
{
	//递归结束条件
	if (pl > pr)
		return NULL;
	//递归表达式
	//首先,从后序遍历中找到根节点
	int newroot = postdata[pr];
	node* newndrt = new node;
	newndrt->data = newroot;
	int k;       //记录root下标的位置
	//其次,从中序遍历中找到相同的值(查找中序序列从头至尾)
	for (int i = il; i <= ir; i++)
	{
		if (indata[i] == newroot)
		{
			k = i;
			break;
		}
	}
	int llength = k - il;//记录左子树的结点个数
	newndrt->lchild = Create(pl, pl + llength - 1, il, k - 1);
	newndrt->rchild = Create(pl+llength, pr-1, k+1, ir);
	return newndrt;   //得返回节点地址呀

}

//先序遍历
void postorder(node *root)
{
	if (root == NULL)
		return;
	cout << root->data << " ";
	postorder(root->lchild);
	postorder(root->rchild);
}

void levelroder(int n,node* root)   //对二叉树进行层次遍历
{
	//首先,将根节点加入队列
	queue<node*> qnodes;
	qnodes.push(root); int cnt = 0;
	while (!qnodes.empty())//当队列非空时
	{
		node* crt = qnodes.front();//取出队首元素,都是以无参函数的形式存在的
		if (cnt != n-1)
			cout << crt->data << " ";
		else
			cout << crt->data;
		cnt++;
		if(crt->lchild!=NULL)
			qnodes.push(crt->lchild);
		if (crt->rchild != NULL)
		qnodes.push(crt->rchild);
		qnodes.pop();   //该元素出栈
		

	}


}



int main()
{
	int n;
	
	
	//接收数据输入
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> postdata[i];
	}
	for (int i = 0; i < n; i++)
	{
		cin >> indata[i];
	}
	//对二叉树进行递归构建
	node* root = new node;
	root = Create(0, n-1, 0, n-1);
	levelroder(n,root);





	system("pause");
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值