剑指offer刷题之c++实现的根据二叉树的前序和中序遍历重建二叉树

#include "myHead.h"
#include "allConstructBinaryTree.cpp" 
/*
利用前序和后序遍历,构造二叉树。
前序第一个节点就是根节点,然后根据这个节点去后序中找到这个数,并记下这个数的下标作为划分的标准。这个数划分了两个范围。
左边一拨全是左子树,右边一拨全是右子树。 可以统计左子树的个数,
下一次,在前序中去掉第一个再开始,以这个中序序列的第二个数为左子树的根,继续在中序的左子树一拨中划分
左右子树。知道叶子节点。如果划分后序的左子树个数为零,那么只有右子树,如果划分后序的右子树个数为零,那么只有左子树。 

*/
    
void create2(TreeNode *&T,vector<int> pre,vector<int> in,int l1,int h1,int l2,int h2);

struct TreeNode* reConstructBinaryTreeByPreIn(vector<int> pre,vector<int> in) {
		int l1,h1,l2,h2;
		TreeNode *T;
        l1 = 0;
        h1 = pre.size()-1;
        l2 = 0;
        h2 = in.size()-1;
       
        printf("first: l1=%d,h1=%d,l2=%d,h2=%d",l1,h1,l2,h2);
		create2(T,pre,in,l1,h1,l2,h2); 
		inOrder(T);
		cout<<"return "<<endl;	
        return T;
    }
    
     void create2(TreeNode *&T,vector<int> pre,vector<int> in,int l1,int h1,int l2,int h2)
	{
		int j=0,l=0;
		printf("\tl1=%d,h1=%d,l2=%d,h2=%d\n",l1,h1,l2,h2);
		T = (TreeNode *) malloc(sizeof(TreeNode)) ;
		T->val = pre[l1];
		cout<<"pre2:"<<T->val<<endl;
        for(j = l2;j<=h2;j++){            
            if(pre[l1] == in[j]){
            	printf("j=%d",j);
                break;
            }
        }         
		l = j-l2;
		
		if(l2 == j){
			cout<<"left null"; 
			T->left = NULL;
		}
		else 
       		create2(T->left,pre,in,l1+1,l1+l,l2,j-1);
        if(h2 == j){
        	cout<<"right null";
        	T->right = NULL;
        } 
        else
        	create2(T->right,pre,in,l1+l+1,h1,j+1,h2); 
	}
    
    
    int main(){
    	vector<int> pre,pre1;
		vector<int> in;
		vector<int> post,post1;
		pre.push_back(1);
		pre.push_back(2); 
		pre.push_back(4);
		pre.push_back(7);
		pre.push_back(3);
		pre.push_back(5);
		pre.push_back(6);
		pre.push_back(8);
		in.push_back(4);
		in.push_back(7);
		in.push_back(2);
		in.push_back(1);
		in.push_back(5);
		in.push_back(3);
		in.push_back(8);
		in.push_back(6);		
	 
		cout<<"pre: ";
		for(vector<int>::iterator it=pre.begin();it<pre.end();++it){
			  cout<<*it<<" ";
		}
		cout<<endl;
		cout<<"in:  ";
		for(vector<int>::iterator it=in.begin();it<in.end();++it){
			  cout<<*it<<" ";
		}
		cout<<endl;
		TreeNode *t =reConstructBinaryTreeByPreIn(pre,in);
		cout<<endl<<"finally";
	    inOrder(t);
		return 1;
	}


 

拓展:根据严格二叉树的前序和后序遍历重建二叉树

#include "myHead.h"
#include "allConstructBinaryTree.cpp" 
/*
利用前序和中序,其中给定的序列的数都不重复,从而构造一颗严格二叉树,
所谓严格二叉树每颗父节点要不都没有左右孩子 ,要不左右子树都不空
但是,显然这个限制条件就不能在普通二叉树中使用了 
*/
void create(TreeNode *&T,vector<int> pre,vector<int> in,int l1,int h1,int l2,int h2);

struct TreeNode* reConstructBinaryTreeByPrePostInConditions(vector<int> pre,vector<int> in) {
		int l1,h1,l2,h2;
		TreeNode *T;
        l1 = 0;
        h1 = pre.size()-1;
        l2 = 0;
        h2 = in.size()-1;
       
        printf("first: l1=%d,h1=%d,l2=%d,h2=%d",l1,h1,l2,h2);
        create(T,pre,in,l1,h1,l2,h2); 
        return T;
    }
    void create(TreeNode *&T,vector<int> pre,vector<int> in,int l1,int h1,int l2,int h2)
	{
	    int i = 0,j=0,l=0;
		printf("l1=%d,h1=%d,l2=%d,h2=%d\n",l1,h1,l2,h2);
		if(l1<= h1)
		    {
				T = (TreeNode *) malloc(sizeof(TreeNode)) ;
				T->val = pre[l1];
	            if(l1 == h1)
				{
	                T->left = NULL;
	                T->right = NULL;				   	
	            }  
	            else
				{ 
	                for(j = l2;j<=h2;j++){
	                    i++;
	                    if(pre[l1+1] == in[j]){
	                        break;
	                    }
	                }
	                i--;
					l = j-l2+1;
	                create(T->left,pre,in,l1+1,l1+l,l2,j);
	                create(T->right,pre,in,l1+l+1,h1,j+1,h2-1); 
			    }
		    } 
    }
    
  
   
    int main(){
    	vector<int> pre1;	
		vector<int> post1;
				
		 pre1.push_back(1);
		 pre1.push_back(2);
		 pre1.push_back(4);
		 pre1.push_back(5);
		 pre1.push_back(3);
		 pre1.push_back(6);
		 pre1.push_back(8);
		 pre1.push_back(9);
		 pre1.push_back(7);
		 pre1.push_back(10);
		 pre1.push_back(11);
		 pre1.push_back(12);
		 pre1.push_back(13);
		 post1.push_back(4);
		 post1.push_back(5);
		 post1.push_back(2);
		 post1.push_back(8); 
		 post1.push_back(9);
		 post1.push_back(6);
		 post1.push_back(10);
		 post1.push_back(12); 
		 post1.push_back(13);
		 post1.push_back(11);
		 post1.push_back(7);
		 post1.push_back(3); 
		 post1.push_back(1); 
	 
		cout<<"pre1:  ";
		for(vector<int>::iterator it=pre1.begin();it<pre1.end();++it){
			  cout<<*it<<" ";
		}
		cout<<endl;
		cout<<"post1:  ";
		for(vector<int>::iterator it=post1.begin();it<post1.end();++it){
			  cout<<*it<<" ";
		}
		cout<<endl;
	
		TreeNode *t =reConstructBinaryTreeByPrePostInConditions(pre1,post1);
		cout<<endl<<"finally:"<<endl;
	    inOrder(t);
		return 1;
	}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值