二叉树重构


#include <iostream>
#include <vector>
//#include <iomanip>
#include <string>


using namespace std;


//先验知识:
//前序:第一个数就是根节点
//中序:根节点位于中间,刚好将其左右子树分开
//运用方法:递归
//找到根节点,将其数值放入value,递归的分别根据左右子树进行二叉树重建
//根据函数已有的接口,因此,需要将左(右)子树的前序,中序分别用vector进行赋值
//最后递归的对左右进行重建,方法一样
//关键:易错点——递归结束的条件:这里直接用了length==0,返回NULL,此时说明该节点是叶子
//每次都是粗心惹的祸,调了一天才发现问题、、、崩溃、、、
struct TreeNode 
{
    int val;
    TreeNode *left;
 	TreeNode *right;
 	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};


TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        int length=vin.size();
        int i=0;
        int locat=0;
       
        //if(length==0||pre.size()==0)
        if(length==0)   //这句话和注释的三句是同样的功能
            return NULL;
        vector<int> newleft,newright,leftpre,rightpre;
        TreeNode* root=new TreeNode(pre[0]);
        //if(length==1&&pre.size()==1&&pre[0]==vin[0])
        //   return root;
        //在中序里找到根节点的位置
        for(i = 0; i<length;i++){
        	if(vin[i]==pre[0]){
                locat=i;
                break;
            }               
        }    
        int j = 0;
        //中序


        for(j=0; j<locat; j++){   
                leftpre.push_back(pre[ j+1]);
            	newleft.push_back(vin[j]);
            	//cout<<pre[j+1]<<endl;//打印输出为了看功能是否完善
            	//cout<<vin[j]<<endl;


       }
       for(j=locat+1;j<length;j++){
                rightpre.push_back(pre[j]);
            	newright.push_back(vin[j]);
            	//cout<<pre[j]<<endl;
            	//cout<<vin[j]<<endl;            
       }    
     


            root->left=reConstructBinaryTree(leftpre,newleft);
  
            root->right=reConstructBinaryTree(rightpre,newright);
       
        return root;
}


void ShowTree(TreeNode* tree)
{	


	if(tree==NULL) return;
	cout<<"\t";
	int root = tree->val;
	//int i = 1;
	//i++;
	//cout.width(3*i);
	cout<<root<<endl;
	
	TreeNode* left = tree->left;
	//i=i*2;
	ShowTree(left);


	TreeNode* right = tree->right;
	
	ShowTree(right);
	
	
}


 int main()
 {
 	vector <int> preorder={1,2,4,7,3,5,6,8};
 	vector <int> inorder={4,7,2,1,5,3,8,6};
 	TreeNode* tmp=reConstructBinaryTree(preorder,inorder);
 	ShowTree(tmp);


 }

//下面这个函数用来层次遍历一棵二叉树,从而从上到下,从左到右打印树
//为了完成层次遍历,用一个队列来保存节点
//如果当前节点有左右节点,则把左右节点分别放入队列,左节点有儿子,则将其儿子按照从左到右的顺序压入队列
//直到队列为空,则打印完毕
//这里借助一个向量依次存放数值,该函数也可以无返回值,每次只要把数字打印出来也可以
vector<int> PrintFromTopToBottom(TreeNode* root) {
	vector<int> printnode;
        if(root==NULL)
            return printnode;
        queue<TreeNode*> queuetreenode;
        queuetreenode.push(root);
        while(queuetreenode.size()){
            TreeNode* p=queuetreenode.front();
            queuetreenode.pop();
            printnode.push_back(p->val);
            if(p->left!=NULL)
                queuetreenode.push(p->left);
            if(p->right!=NULL)
                queuetreenode.push(p->right);
        }
        return printnode;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树重构可以使用递归的方式来实现。具体步骤如下: 1. 定义一个结构体来表示二叉树节点,包含节点值和左右子树两个指针。 ``` struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; ``` 2. 根据给定的前序遍历和中序遍历序列来重构二叉树。在前序遍历序列中,第一个元素为根节点,根据这个节点在中序遍历序列中找到根节点的位置,然后递归地重构左右子树。 ``` TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { if (preorder.empty() || inorder.empty()) { return NULL; } int rootVal = preorder[0]; TreeNode* root = new TreeNode(rootVal); int rootIdx = find(inorder.begin(), inorder.end(), rootVal) - inorder.begin(); vector<int> leftInorder(inorder.begin(), inorder.begin() + rootIdx); vector<int> rightInorder(inorder.begin() + rootIdx + 1, inorder.end()); vector<int> leftPreorder(preorder.begin() + 1, preorder.begin() + 1 + leftInorder.size()); vector<int> rightPreorder(preorder.begin() + 1 + leftInorder.size(), preorder.end()); root->left = buildTree(leftPreorder, leftInorder); root->right = buildTree(rightPreorder, rightInorder); return root; } ``` 3. 在主函数中调用 buildTree() 函数,传入前序遍历和中序遍历序列,即可得到重构后的二叉树。 ``` int main() { vector<int> preorder = {1, 2, 4, 5, 3, 6}; vector<int> inorder = {4, 2, 5, 1, 3, 6}; TreeNode* root = buildTree(preorder, inorder); // do something with the reconstructed binary tree return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值