先序遍历中序遍历后序遍历确定一棵二叉树(递归、非递归)
来源:互联网 发布:图片文字编辑器软件 编辑:程序博客网 时间:2024/05/21 10:54
先序遍历&中序遍历
递归做法:
递归做法比较容易理解,先在先序遍历中确定第一个点,这个点一定是根节点,然后在中序遍历中找到这个点的位置,那么这个位置之前的都是左子树,后边的都是右子树,然后分别递归。
class Solution {public: int start = 0; TreeNode* build(vector<int>& pre,vector<int>& in, int ps,int pe, int is, int ie){ if (ps>=pe) return NULL; int val = pre[ps]; TreeNode* root = new TreeNode(val); int pos; for (int i=is;i<ie;i++){ if (in[i]==val) { pos=i; break; } } root->left = build(pre,in,ps+1,ps+pos-is+1,is,pos); root->right= build(pre,in,pe-ie+pos+1,pe,pos+1,ie); return root; } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { return build(preorder,inorder,0,preorder.size(),0,inorder.size()); }};
非递归:
非递归的做法有些不好理解,核心思想有两点:
1 从先序遍历序列的头部开始从左向右访问,用一个栈保存访问过的节点,每次都要判断栈顶元素是否等于中序遍历的当前节点。
2 如果相等,说明栈顶节点左子树遍历完毕,那么接下来的节点应该是前驱节点的右节点,标志位置1。如果不相等,那么先序遍历的下一个节点依然是前驱节点的左节点或右节点,需要根据标志位确定。
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { stack<TreeNode*> st; int n = int(preorder.size()); if (n == 0) return NULL; int i = 1, j = 0; TreeNode* root = new TreeNode(preorder[0]); bool flag = 0; TreeNode* pre = root; st.push(root); while (i < n){ if (!st.empty() && st.top() -> val == inorder[j]){ pre = st.top(); st.pop(); flag = 1; j++; } else if (flag){ pre -> right = new TreeNode(preorder[i++]); pre = pre -> right; st.push(pre); flag = 0; } else{ pre -> left = new TreeNode(preorder[i++]); pre = pre -> left; st.push(pre); } } return root; }
中序遍历&后序遍历
基本类似,区别是从后向前遍历后序序列
递归:
class Solution {public: int find(vector<int> inorder, int v){ for (int i = 0; i < inorder.size(); ++i){ if (inorder[i] == v) return i; } return -1; } TreeNode* build(vector<int>& inorder, vector<int>& postorder, int s1, int e1, int s2, int e2){ if (s1 > e1) return NULL; else{ int v = postorder[e2]; int index = find(inorder, v); TreeNode* root = new TreeNode(v); root -> left = build(inorder,postorder,s1,index-1,s2,s2+index-1-s1); root -> right = build(inorder,postorder,index+1,e1,s2+index-s1,e2-1); return root; } } TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { int n = inorder.size(); if (n == 0) return NULL; return build(inorder,postorder,0,n-1,0,n-1); }};
非递归
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { int n = inorder.size(); if (n == 0) return NULL; int i = n-1, j = n-2; TreeNode* root = new TreeNode(postorder[n-1]); TreeNode* pre = root; stack<TreeNode*> st; st.push(root); bool flag = 0; while (i >= 0){ if (!st.empty() && st.top() -> val == inorder[i]){ pre = st.top(); st.pop(); i--; flag = true; }else if (flag){ pre -> left = new TreeNode(postorder[j--]); pre = pre -> left; st.push(pre); flag = 0; }else{ pre -> right = new TreeNode(postorder[j--]); pre = pre -> right; st.push(pre); } } return root; }
0 0
- 先序遍历中序遍历后序遍历确定一棵二叉树(递归、非递归)
- 二叉树 非递归 先序遍历 中序遍历 后序遍历 层次遍历
- 二叉树的遍历(2)--先序遍历,中序遍历,后序遍历(非递归)
- 二叉树非递归先序遍历、中序遍历、后序遍历
- 二叉树遍历(先序遍历、中序遍历、后序遍历)——递归方法和非递归方法
- 二叉树的先序、中序、后序递归遍历和非递归遍历
- 二叉树(一) 先序遍历、中序遍历、后续遍历、层次遍历的递归与非递归实现
- 二叉树的先序/中序/后序(递归、非递归)+层序遍历
- 二叉树非递归和递归遍历(先序,中序,后序)
- 二叉树的先序、中序、后序遍历(递归 and 非递归)
- 二叉树的先序遍历、中序遍历以及后序遍历(递归以及非递归方式)
- 非递归先序遍历二叉树、非递归中序遍历二叉树、非递归后序遍历二叉树
- 二叉树2:层次遍历方式及先序、中序、后序(递归与非递归)遍历方式
- 非递归先序遍历二叉树
- 非递归先序遍历二叉树
- 先序遍历二叉树 [非递归]
- 非递归先序遍历二叉树
- 二叉树非递归先序遍历
- [Leetcode] Insert Interval
- 20162017-ct-s03e02-codeforces-trainings-season-3-episode-2-en-A HHPaint
- Poedu_C语言_lesson13_20160912_字符串
- C++ 中的运算符重载
- Spring Boot交流平台
- 先序遍历中序遍历后序遍历确定一棵二叉树(递归、非递归)
- java中堆和栈有什么区别
- eMMC Firmware Upgrade
- Swift- 枚举中的rawValue和hashValue
- java编程思想(二)总结
- kafka 0.10.0 producer java代码实现
- Scroll Indicator(javascript实现)
- 数据结构-2
- BroadcastReceiver应用