二叉树面试题(一) 重建二叉树

问题描述:

由前序遍历和中序遍历重建二叉树(前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)数据不含重复值。

题目分析如下


前序遍历序列1 2 3 4 5 6前序遍历规则是根--左--右

中序遍历序列3 2 4 1 6 5,中序遍历规则是左--根--右


1.由前序遍历可知根节点一定为第一个元素1,在中序遍历序列中找到1对应位置,判断根节点1的左右子树是否为空,1的左右都不为空,1的左边就是左子树324,右边就是右子树56;

2.再根据前序遍历规则可知,左子树序列里第一个就是左子树的根节点2,右子树序列里的第一个就是右子树的根节点5,用上次的方法递归建立左右子树。



3.再根据中序遍历序列可知,左子树根节点2左边的一定是以其为根节点的左子树序列3右边就是以其为根节点的右子树序列4

右子树根节点5左边的一定是以其为根节点的右子树序列6,直至序列为空,就可以完整重建二叉树了


代码实现:

#include<iostream>
#include<cassert>
using namespace std;
struct NewTreeNode
{
	NewTreeNode* _left;
	NewTreeNode* _right;
	int _value;
	NewTreeNode(int value)
		:_value(value)
		,_left(NULL)
		,_right(NULL)
	{}
};


typedef NewTreeNode Node;

  
Node* _RebuildTree(int *startPre,int *endPre,int *startIn,int *endIn)  
{   
    Node *root = new Node(startPre[0]); 
	//_left和_right已初始化为NULL
    if(startIn == endIn && *startIn == *startIn)  
    {  
        return root;  
    }  
    //4.根据此根节点在中序中找此节点的位置  
    int * rootIn = startIn;  
    while(*startPre != *rootIn)  
    {  
        rootIn++;  
    }  
    //根据此根节点在中序遍历中的位置,递归还原左子树  
    int leftlen = rootIn-startIn;  
    if(leftlen>0)  
    {  
        root->_left = _RebuildTree(startPre+1,startPre+leftlen,startIn,startIn+leftlen-1);  
  
    }  
    if(leftlen+startIn < endIn)//该节点还存在右子树,所以继续递归还原右子树  
    {//递归还原右子树  
        root->_right = _RebuildTree(startPre+leftlen+1,endPre,startIn+leftlen+1,endIn);  
    }  
    return root;  
}

Node*  RebuildTree(int* PreOrder,int* InOrder,int len)  
{  
    if(PreOrder == NULL || InOrder == NULL )  
        return NULL;    
    else    
        return _RebuildTree(PreOrder,PreOrder+len-1,InOrder,InOrder+len-1);  
}  

void PostOrder(Node *root)  
{  
	if(root->_left != NULL)  
		PostOrder(root->_left); 

	if(root->_right != NULL)  
		PostOrder(root->_right);  

	cout<<root->_value<<" ";  
}  
void PrevOrder(Node *root)  
{  
	if(root==NULL)
		return;
	cout<<root->_value<<" ";
	if(root->_left != NULL)  
		PrevOrder(root->_left); 

	if(root->_right != NULL)  
		PrevOrder(root->_right);    
}  


int main()  
{  
    int PreOrder[] = {1,2,3,4,5,6};  
    int InOrder[] = {3,2,4,1,6,5};  
    int PreSize=sizeof(PreOrder)/sizeof(PreOrder[0]);
    int InSize=sizeof(InOrder)/sizeof(InOrder[0]);
	if(PreSize!=InSize)
	{
		cout<<"所给数据错误"<<endl;
		return -1;
	}
    NewTreeNode* root = RebuildTree(PreOrder,InOrder,PreSize);  
	PrevOrder(root);//123456
    cout<<endl; 

    PostOrder(root);//342651  
    cout<<endl;  
	 
    system("pause");  
    return 0 ;  
}
在此运用前序和后序检查该树是否正确

运行结果:


                   
    未完,后续还有部分关于二叉树面试题!待续!


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值