重建二叉树

   二叉树有三种基本的遍历方式:前序遍历(根节点-左节点-右节点)、中序遍历(左节点-根节点-右节点)和后续遍历(左节点-右节点-根节点)。每一种遍历方式得到的序列并不能唯一的确定一棵二叉树,需要结合,比如中序遍历和前序遍历、中序遍历和后序遍历都能够唯一地确定一棵二叉树,但是前序遍历和后序遍历却唯一地确定二叉树(我理解为前序遍历和后序遍历左右节点的相对位置是一样的,所以没有办法唯一的确定左右节点的位置)。

示例

根据前序遍历和中序遍历确定二叉树:
前序遍历结果:{1,2,4,7,3,5,6,8},
中序遍历结果:{4,7,2,1,5,3,8,6}
前序遍历和中序遍历然后递归的建立左右子树即可,代码如下:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
		int index=0;
		int len=vin.size();	
		if(len<1) return NULL;
        int i;
		for(i=0;i<len;i++)
			if(vin[i] == pre[0])
			{
				index=i;
				break;
			}

		vector<int> left_pre,right_pre;
		vector<int> left_vin,right_vin;
		for(i=0;i<index;i++){
			left_vin.push_back(vin[i]);
			left_pre.push_back(pre[i+1]);
		}
		for(i=index+1;i<len;i++){
			right_vin.push_back(vin[i]);
			right_pre.push_back(pre[i]);

		}
		TreeNode* root=new TreeNode(pre[0]);
		root->left=reConstructBinaryTree(left_pre,left_vin);
		root->right=reConstructBinaryTree(right_pre,right_vin);
		left_vin.clear();
		right_vin.clear();
		left_pre.clear();
		right_pre.clear();
		return root;
    }
};

   二叉树还有一种基本遍历方式,即层序遍历,由于遍历过程中,左右子树相对位置同前序和后序遍历,因此将其和中序遍历结果结合使用,仍然可以唯一地确定一棵二叉树。
比如层序遍历结果:{3,5,4,2,6,7,1}
中序遍历结果:{2,5,3,6,4,7,1}
层序遍历和中序遍历   使用层序遍历和中序遍历结果去确定一棵二叉树的方法和使用前序中序遍历结果不同,当确定了左右子树的元素之后,在层序遍历结果中出现最早的就是左右子树的根节点,所以每一次对左右子树进行递归的时候,都需要遍历层序遍历的结果,找到当前还没有被访问到的最前面的节点元素。代码如下:

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
struct TreeNode{
	int val;
	TreeNode *left,*right;
	TreeNode(int x):val(x),left(NULL),right(NULL){}
};
class Solution{
private:
	TreeNode* root;
	vector<int> leaf;
	vector<int> lev;
	vector<int> vin;
	vector<int> visit;
public:
	void construct(vector<int> lev_tree,vector<int> vin_tree){
		lev=lev_tree;
		vin=vin_tree;
		lev_tree.clear();
		vin_tree.clear();
		int len=vin.size();
		visit.resize(len,0);
		root=construct_Tree(0,len-1);
	}

	TreeNode* construct_Tree(int left,int right){
		if(left>right)return NULL;
		TreeNode* root=NULL;
		int i,index,j;
		int flag=0;
		for(i=0;i<lev.size();i++){
			if(visit[i]==0)
				for(j=left;j<=right;j++)
					if(vin[j]==lev[i]){
						index=j;
						flag=1;
						break;
					}
			if(flag)
				break;
		}
		if(flag){
			visit[i]==1;
			if((index==left) && (right==index))
				leaf.push_back(vin[left]);
			root=new TreeNode(vin[index]);
			root->left=construct_Tree(left,index-1);
			root->right=construct_Tree(index+1,right);
	
		}
		return root;
	}
	
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值