C++ 已知二叉树两种遍历序列,构建二叉树

  • 已知先序遍历和中序遍历,可以求出后序遍历
  • 已知后序遍历和中序遍历,可以求出先序遍历
  • 已知先序遍历和后序遍历不可求出中序遍历

1.已知先序遍历和中序遍历,求后序遍历

1.1 解题思想:

        由先序遍历的特点可知,先序遍历第一个元素为二叉树的根。由中序遍历的特点可知,二叉树的左面为左子树的中序遍历右面为右子树的中序遍历。由先序遍历可以知道二叉树的根,由中序遍历可以知道二叉树的左子树和右子树,因此,我们可以用递归的思想,将整个二叉树递归分解成左子树和右子树,直到子树为空为止。

1.2 实现细节:

        已知先序遍历是先遍历当前二叉树的根,然后递归遍历左子树和右子树。再由中序遍历根的位置可以得出左子树和右子树的长度(大小)。再将左右子树的长度带入先序遍历,就可以得出左子树的先序遍历和右子树的先序遍历,结合左右子树的中序遍历,就可以递归求解

1.3 参考代码:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

vector <char > post;
string pre, mid;

void solve(int l1, int r1, int l2, int r2)
{
    if(r1 < l1)
        return ;
    post.push_back(pre[l1]);//将根按顺序存在数组里
    int q = l2;
    while(pre[l1] != mid[q]) q++;//在中序中找到根
    int cnt = q - l2;//左子树元素个数 
//先遍历右子树在遍历左子树,这样就可以按照 根、右、左顺序存在容器中,倒序输出即为答案 
    solve(l1 + cnt+1, r1, q+1, r2);//递归右子树 
	solve(l1+1, l1+cnt, l2, q-1);//递归左子树 
}

int main()
{
    while(cin >> pre >> mid)
    {
        post.clear();
        solve(0, pre.size()-1, 0, mid.size()-1);
        //倒序输出
        for(int i = post.size() - 1; i >= 0; i--)
        {
            cout << post[i];
        }
        cout << endl;
    }
    return 0;
}


2.已知后序遍历和中序遍历,求先序遍历

2.1解题思想:

        总体思想和用先序、中序求后序相同。后序遍历是先遍历左右子树,最后才是根。因此,后序遍历最后一个元素是二叉树的根在中序遍历找到根的位置,根的左面就是左子树的中序遍历,右边就是右子树的先序遍历,根据其长度,将后序遍历分成左右子树的后序遍历。

2.2 实现细节:

        假设中序遍历中,根的左面有lenA个元素,右边有lenB个元素,那么就可以知道其左子树有lenA个元素,右子树有lenB个子树。由后序遍历的特点可知,最后一个元素为根,根的前面lenB个元素为右子树的后序遍历,在这些元素前面的lenA个元素为左子树的后序遍历,因此可以递归求解。

2.3 代码实例:

#include<iostream>
#include<string>
using namespace std;
string mid,post;
string ans;
void solve(int l1,int r1,int l2,int r2){
	if(r1 < l1)	return;
	int p = l2;
	ans+=post[r1];
	while(post[r1] != mid[p])	p++;
	int len = p - l2;
	solve(l1,r1-len-1,l2,l2+len-1);
	solve(r1-len,r1-1,l2+len+1,r2);
}
int main()
{
	while(cin >> post >> mid){
		solve(0,post.length()-1,0,mid.length()-1);
		cout << ans << endl;
	}
	return 0;
} 

原文地址:https://www.cnblogs.com/long98/p/10352241.html