利用二叉树的先序和中序(中序和后序)排列构建二叉树

题目来自于:

https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

这一题目其实我想说的还不是我的代码,是之前在写代码中遇到的一个bug问题。后面会进行详细的解释

Construct Binary Tree from Preorder and Inorder Traversal

Total Accepted: 35628 Total
Submissions: 134968My Submissions

Question
 Solution

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:

You may assume that duplicates do not exist in the tree.

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
TreeNode* buildhelp(vector<int>& preorder, vector<int>& inorder,int pStart,int pEnd,int iStart,int iEnd){
      if(pStart>pEnd||iStart>iEnd)
      return NULL;
      TreeNode *Tnode=new TreeNode(preorder[pStart]);
      if(pStart==pEnd)
      return Tnode;
      int cur=iStart;
      while(inorder[cur]!=preorder[pStart])
          cur++;
  Tnode->left=buildhelp(preorder, inorder,pStart+1,pStart+(cur-iStart),iStart,cur-1);
  Tnode->right=buildhelp(preorder, inorder,pEnd-(iEnd-cur-1),pEnd,cur+1,iEnd);
      return Tnode;
  }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        TreeNode* Tree=NULL;
        if(preorder.size()==0)
         return Tree;
        Tree=buildhelp(preorder, inorder,0,preorder.size()-1,0,inorder.size()-1);
        return Tree;
    }
};

上述代码是正确的可以AC的,但是本人在第一次写的时候写成了

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
TreeNode* buildhelp(vector<int>& preorder, vector<int>& inorder,int pStart,int pEnd,int iStart,int iEnd){
      if(pStart<pEnd||iStart<iEnd)
      return NULL;
      TreeNode Tnode(preorder[pStart]);
      if(pStart==pEnd)
      return &Tnode;
      int cur=iStart;
      while(inorder[cur]!=preorder[pStart])
          cur++;
  Tnode.left=buildhelp(preorder, inorder,pStart+1,pStart+(cur-iStart),iStart,cur-1);
  Tnode.right=buildhelp(preorder, inorder,pEnd-(iEnd-cur-1),pEnd,cur+1,iEnd);
      return &Tnode;
  }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        TreeNode* Tree=NULL;
        if(preorder.size()==0)
         return Tree;
        Tree=buildhelp(preorder, inorder,0,preorder.size()-1,0,inorder.size()-1);
        return Tree;
    }
};

不同的地方在于

  TreeNode Tnode(preorder[pStart]);

然后返回其指针

这里犯了一个很大的错误就是,其实每次算法在遇到该处时候只是将结构体中的成员变量替换成了新的,却没有构建新的节点。

为了验证我们的想法:

#include<iostream>
#include<vector>
using namespace std;
 struct TreeNode {
     int val;
     TreeNode *left;
     TreeNode *right;
      TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  };

int main()
{
	int i=5;
 while(i--)
 {
  TreeNode aa(i);
  cout<<&aa<<endl;
 }

}

我们在一个while中多次重建该结构体但是其地址都没有发生改变

最后是第二道类似的算法

Construct Binary Tree from Inorder and Postorder Traversal

Total Accepted: 32565 Total
Submissions: 121341My Submissions

Question
 Solution

Given inorder and postorder traversal of a tree, construct the binary tree.

Note:

You may assume that duplicates do not exist in the tree.

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:

TreeNode* buildhelp(vector<int>& inorder, vector<int>& postorder,int iStart,int iEnd,int pStart,int pEnd){
      if(pStart>pEnd||iStart>iEnd)
      return NULL;
      TreeNode Tnode(postorder[pEnd]);
      if(pStart==pEnd)
      return &Tnode;
      int cur=iStart;
      while(inorder[cur]!=postorder[pEnd])
          cur++;
  Tnode.left=buildhelp(inorder, postorder,iStart,cur-1,pStart,pStart+(cur-iStart-1));
  Tnode.right=buildhelp(inorder, postorder,cur+1,iEnd,pEnd-1-(iEnd-cur-1),pEnd-1);
      return &Tnode;
  }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
         if(inorder.size()==0)
         return NULL;
        return buildhelp(inorder, postorder,0,inorder.size()-1,0,postorder.size()-1);
    }
};
时间: 06-18

利用二叉树的先序和中序(中序和后序)排列构建二叉树的相关文章

已知二叉树的前序遍历和中序遍历,如何得到它的后序遍历?

对一棵二叉树进行遍历,我们可以采取3中顺序进行遍历,分别是前序遍历.中序遍历和后序遍历.这三种方式是以访问父节点的顺序来进行命名的.假设父节点是N,左节点是L,右节点是R,那么对应的访问遍历顺序如下: 前序遍历    N->L->R 中序遍历    L->N->R 后序遍历    L->R->N /***************************************************************************************

二叉查找树中由前序转化为后序

1 void getPostFromPre(int preL, int preR) { 2 if (preL > preR) return; 3 int i = preL + 1, j = preR; 4 while (i <= preR && pre[i] < pre[preL]) i++; 5 while (j > preL&&pre[j] >= pre[preL]) j--; 6 7 if (i - j != 1) return; 8 g

根据先序和中序序列构建二叉树

说明: 本次实验利用中序和先序序列,采用递归方式来构建二叉树 . 经过几天的失败和思考,我认为递归构建二叉树的过程中最重要的是递归单元,最麻烦的是递归参数的选择和传递. 简单将算法过程用如下流程图来表示:(本帖所用算法及图片均为原创内容,转贴注明出处) 算法:1.根据先序序列,建立根结点T 2.寻找中序序列的根结点位置,并据此位置计算左子树和右子树的区间 3.判断l_start和r_end是否相等,相等则表示只有一个根结点,设置其左右孩子结点为空并结束这一层:若不相等则继续下面步骤: 4.根据2

【基础备忘】 二叉树前序、中序、后序遍历相互求法

转自:http://www.cnblogs.com/fzhe/archive/2013/01/07/2849040.html 今天来总结下二叉树前序.中序.后序遍历相互求法,即如果知道两个的遍历,如何求第三种遍历方法,比较笨的方法是画出来二叉树,然后根据各种遍历不同的特性来求,也可以编程求出,下面我们分别说明. 首先,我们看看前序.中序.后序遍历的特性: 前序遍历:     1.访问根节点     2.前序遍历左子树     3.前序遍历右子树 中序遍历:     1.中序遍历左子树     2

树(二叉树)的建立和遍历算法(一)(前序,中序,后序)

最近学习树的概念,有关二叉树的实现算法记录下来... 不过学习之前要了解的预备知识:树的概念:二叉树的存储结构:二叉树的遍历方法.. 二叉树的存储结构主要了解二叉链表结构,也就是一个数据域,两个指针域,(分别为指向左右孩子的指针),从下面程序1,二叉树的存储结构可以看出. 二叉树的遍历方法:主要有前序遍历,中序遍历,后序遍历,层序遍历.(层序遍历下一篇再讲,本篇主要讲的递归法) 如这样一个二叉树: 它的前序遍历顺序为:ABDGHCEIF(规则是先是根结点,再前序遍历左子树,再前序遍历右子树) 它

二叉树的前序、中序、后序遍历的递归和非递归算法实现

1 /** 2 * 二叉树的前序.中序.后序遍历的递归和非递归算法实现 3 **/ 4 5 //二叉链表存储 6 struct BTNode 7 { 8 struct BTNode *LChild; // 指向左孩子指针 9 ELEMENTTYPE data; // 结点数据 10 struct BTNode *RChild; // 指向右孩子指针 11 }; 12 13 /** 14 * 前序遍历 15 **/ 16 // 递归实现 17 void PreorderTraversal(BTNo

Construct Binary Tree from Inorder and Postorder Traversal ——通过中序、后序遍历得到二叉树

题意:根据二叉树的中序遍历和后序遍历恢复二叉树. 解题思路:看到树首先想到要用递归来解题.以这道题为例:如果一颗二叉树为{1,2,3,4,5,6,7},则中序遍历为{4,2,5,1,6,3,7},后序遍历为{4,5,2,6,7,3,1},我们可以反推回去.由于后序遍历的最后一个节点就是树的根.也就是root=1,然后我们在中序遍历中搜索1,可以看到中序遍历的第四个数是1,也就是root.根据中序遍历的定义,1左边的数{4,2,5}就是左子树的中序遍历,1右边的数{6,3,7}就是右子树的中序遍历

二叉树前序、中序、后序遍历相互求法

今天来总结下二叉树前序.中序.后序遍历相互求法,即如果知道两个的遍历,如何求第三种遍历方法,比较笨的方法是画出来二叉树,然后根据各种遍历不同的特性来求,也可以编程求出,下面我们分别说明. 首先,我们看看前序.中序.后序遍历的特性: 前序遍历:     1.访问根节点     2.前序遍历左子树     3.前序遍历右子树 中序遍历:     1.中序遍历左子树     2.访问根节点     3.中序遍历右子树 后序遍历:     1.后序遍历左子树     2.后序遍历右子树     3.访问

二叉树的前序中序后序遍历相互求法

二叉树的前中后序遍历,他们的递归非递归.还有广度遍历,参见二叉树的前中后序遍历迭代&广度遍历和二叉树的前中后序遍历简单的递归 现在记录已知二叉树的前序中序后序遍历的两个,求另外一个.一般,这两个中一定有中序遍历. 1.已知前序和中序,求后序遍历: 前序:ABDECFG  中序:DBEAFCG 思路简单:前序的第一个节点就是根节点, 中序中找到根节点的位置,根节点之前是其左子树,之后是右子树   按此顺序,依次在左子树部分遍历,右子树部分遍历 C++ 代码: TreeNode *BinaryTre