【剑指offer JZ4】重建二叉树 --C++实现
重建二叉树
http://www.nowcoder.com/questionTerminal/8a19cbe657394eeaac2f6ea9b0f6fcf6
1. 解题思路
- 首先要明白 先序,中序,后序遍历(就是根左右,左根右,左右根)
- 样例先序遍历:[1,2,3,4,5,6,7] 中序遍历:[3,2,4,1,6,5,7]
1)起初范围就是整个先序列表和中序列表 ,先序的每个依次作为根节点
2)首先是1 对应中序数组下标[3],则3,2,4为左子树的内容,6,5,7为右分支的内容
2. 源代码来自chain20190719194071
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode* build(vector<int>& pre, int pre_left, int pre_right, vector<int>& vin, int vin_left, int vin_right) { if (pre_left > pre_right) return nullptr;//判断该准备做根的节点存在 int value = pre[pre_left];//取出当前根的值 TreeNode* root = new TreeNode(value);//建立根节点 for (int i = vin_left; i <= vin_right; ++i) {//i从中序开始找的位置 if (vin[i] == value) {//找到先序根节点对应的中序位置 //这步 进行递归 寻找左右子树树 //根的左孩子指向节点为(先序根 ) //参数1.传递完整先序队列参数 //参数2. 本次先序根+1取新作为左子树根节点,但左子树其实不一定存在,需要划定右端点判断 //参数3. 限定左子树在先序的右端点,当前根节点位置+左子树个数(当前在中序位置-开始中序开始的位置) //参数4.传递中序队列参数 //参数5. 中序左端点不变 //参数6. 中序变右边界(i-1) root->left = build(pre, pre_left + 1, pre_left + i - vin_left, vin, vin_left, i - 1); //根的右孩子指向节点为( ) //参数1.先序队列不变 //参数2. 下个先序右节点=本次先序根+几个左子树(i-中序初始位置)+1,但右子树其实不一定存在,需要划定右端点判断 //参数3. 限定右端点不变 //参数4.中序队列不变 //参数5. 中序变左端点(i+1) //参数6. 中序右边界不变 root->right = build(pre, pre_left + i - vin_left+1, pre_right,vin, i + 1, vin_right); break; } } return root; } //返回头结点类型的 初始 //参数1.先序遍历数组 //参数2. 每次先序的定根节点 首次为0 //参数3. 匹配先序右端点 //参数4.中序遍历数组 //参数5. 中序开始找的位置 //参数6. 中序右端点 TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { return build(pre, 0, pre.size() - 1, vin, 0, vin.size() - 1);//数组名 } };