欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从前序/后序遍历与中序遍历构造二叉树

程序员文章站 2024-03-19 20:52:40
...

题目

从前序/后序遍历与中序遍历构造二叉树

思路

先知道一个定律:从前序/后序遍历+中序遍历可以确定一棵不存在相同节点的二叉树
我们先复习一下深度优先的三个遍历:

  1. 前序遍历:根节点——左子树——右子树
  2. 中序遍历:左子树——根节点——右子树
  3. 后序遍历:左子树——右子树——根节点
所以当我们知道前序遍历和中序遍历后,大体思路如下:
  1. 前序遍历的第一个为根节点
  2. 接着我们去中序遍历中寻找根节点所在位置,那么根节点前面的就是左子树所有的节点,右边就是右子树所有的节点
  3. 总的来说,前序遍历就是[根节点,左子树,右子树],中序遍历就是[左子树,根节点,右子树]
    代码如下:
class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
		return Build(preorder, 0, preorder.size()-1, inorder, 0, inorder.size()-1);
	}
	TreeNode* Build(vector<int>&pre,int left1,int right1,vector<int>& in,int left2,int right2) {
		if (left1 > right1 || left2 > right2)
			return NULL;
		TreeNode* root = new TreeNode(pre[left1]);//前序遍历的第一个节点为根节点
		//然后在中序遍历中确定左子树和右子树的节点个数
		int mid = left2;
		for (int i = left2; i < in.size(); i++) {
			if (in[i] == root->val) {
				mid = i;
				break;
			}
		}
		//构建左子树
		root->left = Build(pre, left1 + 1, left1+mid-left2, in, left2, mid-1);
		root->right = Build(pre, left1 + mid - left2 + 1, right1, in, mid + 1, right2);
		return root;
	}
};
知道后序遍历和中序遍历后的大体思路如下:
  1. 后序遍历最后一个节点为根节点
  2. 在中序遍历中寻找根节点所在位置,根节点前面的节点就为左子树所有节点,根节点后边的节点就为右子树所有节点
  3. 总的来说,后序遍历就是[左子树,右子树,根节点],中序遍历就是[左子树,根节点,右子树]
    代码如下:
class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
		return Build(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);
	}
	TreeNode* Build(vector<int>& in, int left1, int right1, vector<int>& post, int left2, int right2) {
		if (left1 > right1 || left2 > right2) 
			return NULL;
		TreeNode* root = new TreeNode(post[right2]);
		int mid = left1;
		for (int i = left1; i <= right1; i++) {
			if (in[i] == root->val) {
				mid = i;
				break;
			}
		}
		root->left = Build(in, left1, mid - 1, post, left2, left2 + mid - left1-1);
		root->right = Build(in, mid + 1, right1, post,left2 + mid - left1, right2 - 1);
		return root;
	}
};

总结

重构二叉树的基本思路就是先构造根节点,再构造左子树,接下来构造右子树,其中构造左子树和右子树是一个子问题,递归处理即可。因此我们只关心如何构造根节点,以及如何递归构造左子树和右子树,再从前序,中序,后序遍历的特点来寻找根节点,左子树和右子树各自的范围

相关标签: LeetCode