下面有彩蛋
题目描述
输入一棵二叉树前序遍历和中序遍历的结果,请重建该二叉树。
注意:
- 二叉树中每个节点的值都互不相同;
- 输入的前序遍历和中序遍历一定合法;
样例
Input:
前序遍历:[3,9,20,15,7]
中序遍历:[9,3,15,20,7]
Output: [3,9,20,null,null,15,7,null,null,null,null]
返回的二叉树如下所示:
3
/ \
9 20
/ \
15 7
解题思路
-
描述
对于涉及二叉树问题,一般都会使用到递归。前序遍历(根左右)和中序遍历(左根右)获取整个二叉树的方法:
- 获取前序遍历的第一个元素,也就是根。
- 在中序遍历中,该根元素会将中序遍历结果分解为两部分,前半部分为左子树,后半部分为右子树。
- 根据上面左右子树的个数,在前序遍历中可以得到相应子树的前序遍历
-
实现代码:
/* 使用到的头文件 #include <vector> #include <map> 结构体 struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int val) { this->val = val; this->left = NULL; this->right = NULL; } }; */ map<int, int> hashIndex; //存储中序遍历元素的位置 vector<int> preorder; //全局变量存储前序和中序遍历,方便使用dfs vector<int> inorder; //递归实现重建二叉树 //pl,pr表示前序遍历元素下标范围[pl,pr],il,ir表示中序遍历元素下标范围[il,ir] TreeNode* dfs(int pl, int pr, int il, int ir) { if (pl > pr) //表示不存在根元素,返回NULL { return NULL; } TreeNode* root = new TreeNode(preorder[pl]); //获取根节点 int k = hashIndex[preorder[pl]]; //获取该根节点在中序遍历中的位置 //左右子树对应前序遍历和中序遍历下标范围 root->left = dfs(pl + 1, pl + k - il, il, k - 1); root->right = dfs(pl + k - il + 1, pr, k + 1, ir); return root; //返回该根节点 } TreeNode* buildTree(vector<int> &_preorder, vector<int> &_inorder) { preorder = _preorder; inorder = _inorder; for (int i = 0; i < inorder.size(); i++) { hashIndex[inorder[i]] = i; //使用hashIndex记录中序遍历每一个元素的位置 } return dfs(0,preorder.size() - 1,0 ,inorder.size()); }
二叉树层序遍历
/*
使用到的头文件
#include <queue>
*/
void print(TreeNode* head)
{
TreeNode* tmp;
queue<TreeNode*> que;
if (head == NULL)
{
return ;
}
que.push(head);
while (!que.empty())
{
tmp = que.front();
que.pop();
if (tmp == NULL)
{
cout << "null" << " ";
}
else
{
cout << tmp->val << " ";
que.push(tmp->left);
que.push(tmp->right);
}
}
}