LeetCode105:从前序与中序遍历序列构造二叉树

原题:

根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

解答:

这个题目也是剑指offer中的一道题目,思路比较清晰,就是先序遍历的第一个元素rootValue是根元素,然后去中序遍历的序列中找到rootValue的位置,就可以把中序遍历序列中的元素分为左右两部分,左边是左子树上的元素,右边是右子树上的元素,然后分别对左右两边进行递归调用函数,最后返回根结点,就是答案了。

代码:

struct TreeNode {
     int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 };

 TreeNode* buildTree(vector<int>& preorder, int pLeft, int pRight,
	 vector<int>& inorder, int iLeft, int iRight)
 {
	 if (preorder.empty())//如果序列为空
		 return nullptr;
	 if (pLeft == pRight)//如果只有一个元素
	 {
		 TreeNode *item = new TreeNode(preorder[pLeft]);
		 item->left = nullptr;
		 item->right = nullptr;
		 return item;
	 }
	 int key = preorder[pLeft];
	 int index = iLeft;
	 for (int i = iLeft; i <= iRight; i++)
	 {
		 if (inorder[i] == key)
		 {
			 index = i;
			 break;
		 }
	 }
	 TreeNode *root = new TreeNode(key);
	 if(index>iLeft)//左边有元素
		root->left = buildTree(preorder, pLeft + 1, pLeft + index - iLeft, inorder,     
                              iLeft, index - 1);
	 if(index<iRight)//右边有元素
		root->right = buildTree(preorder, pLeft + index - iLeft + 1, pRight, inorder, 
                              index + 1, iRight);
	 return root;
 }

 TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
 {
	 return buildTree(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1);
 }

     需要注意的是,原题给的函数是只有前序和后序两个序列作为输入的,因为我们需要知道要构造二叉树的元素的位置,所以需要分别加上范围,然后再进行编码。递归函数要注意出口的判断条件,在构造左右子树时也要判断是否有元素存在。

猜你喜欢

转载自blog.csdn.net/qq_36214481/article/details/84657110