根据前序和中序遍历序列创建二叉树

【问题描述】

已知一个二叉树的前序遍历序列和中序遍历序列,求这棵树的后序遍历序列。

【输入形式】

一棵树的前序遍历序列和中序遍历序列,中间用换行符分开。输入序列中仅包含大小写字母,且没有重复的字母

【输出形式】

一个树的后序遍历序列

【样例输入】

ABCDEFGHI

BCAEDGHFI

【样例输出】

后序遍历:CBEHGIFDA

【思路】

首先找根节点的位置,因为有前序遍历,第一个节点就是根节点,然后在中序遍历中以找出的根节点为界划分左右子树,用递归构建出二叉树,再用后序遍历输出。

【题解代码】

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int MAX = 1000;
struct BiNode
{
	char data;//数据域
	BiNode* lchild, * rchild;//左右儿子指针
};

class BiTree {
private:
	BiNode* root;
public:
	//prestr是前序输入的字符串,instr是中序输入的字符串
    BiTree(string prestr,string instr) 
	{ 
		int lenpre = prestr.length();
		int lenin = instr.length();
		if (lenpre != lenin)root = NULL;//检查
		else
		{
			root = creat(root, prestr, instr);//创建根节点
		}
	}
    ~BiTree() {
        release(root);
    }
    BiNode* getRoot() { return root; }
    BiNode* creat(BiNode* bt,string prestr,string instr); //构造函数调用
    void release(BiNode* bt);  //析构函数调用,释放树的存储空间
	void preOrder(BiNode* bt);
	void postOrder(BiNode* bt);
	void inOrder(BiNode* bt);

}; 
//创建二叉树
BiNode* BiTree::creat(BiNode* bt, string prestr, string instr)//prestr是前序输入的字符串,instr是中序输入的字符串
{
	if (prestr.length() == 0 || instr.length() == 0)//检查
		return NULL;
	else
	{
		int pos;//用来记录查找的根节点的位置下标
		pos = instr.find(prestr[0]);//调用find函数在instr中查找根节点的下标并记录在pos中,
		bt = new BiNode;
		bt->data = prestr[0];//存储根节点
		string prelstr = prestr.substr(1, pos);//prelstr用来保存根节点的左子树,用substr函数将左子树找到并保存在prelstr中。因为此时根节点在prestr中的第一个位置,所以截取的时候要从第二个位置开始,也就是从下标为1的位置开始
		//pos也是要截取的字符串的长度,因为中序串的左侧都是左子树的结点,其节点个数就等于pos
		string inlstr = instr.substr(0, pos);//同理,inlstr用来保存在instr中找到的左子树,此时的根节点并不在第一个位置,所以截取的时候要从头开始找,也就是从下标为0的位置开始
		string prerstr = prestr.substr(pos + 1, prestr.length() - pos - 1);//再取右子树,因为这个是前序串嘛,前面已经把左子树和根节点都取到了,剩下的就都是右子树了,因此从根节点的后一位开始,到串结束为止都要截取,所以截取的长度是len-1-pos
		string inrstr = instr.substr(pos + 1, instr.length() - pos - 1);//同理
		bt->lchild = creat(bt->lchild, prelstr, inlstr);//已经取到左右子树了,那就递归创建呗
		bt->rchild = creat(bt->rchild, prerstr, inrstr);
		return bt;

	}
	return bt;
}

void BiTree::release(BiNode* bt)
{
	if (bt != NULL)
	{
		release(bt->lchild);
		release(bt->rchild);
		delete bt;
	}
}

void BiTree::preOrder(BiNode* bt)
{
	if (bt == NULL)
	{
		return;
	}
	preOrder(bt->lchild);
	preOrder(bt->rchild);
}
void BiTree::postOrder(BiNode* bt)
{
	if (bt == NULL)
	{
		return;
	}
	postOrder(bt->lchild);
	postOrder(bt->rchild);
	cout << bt->data;
}
void BiTree::inOrder(BiNode* bt)
{
	if (bt == NULL)
	{
		return;
	}
	inOrder(bt->lchild);
	inOrder(bt->rchild);
}

int main()
{
	string s1, s2;
	cin >> s1 >> s2;
	BiTree tree(s1,s2);
	cout << "后序遍历:";
	tree.postOrder(tree.getRoot());//后序输出二叉树
	cout << endl;
	return 0;
}

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值