LeetCode Binary Tree Inorder Traversal
class Solution { public: vector<int> inorderTraversal(TreeNode *root) { vector<int> res; if (root == NULL) return res; vector<pair<TreeNode*, bool> > stack; stack.push_back(make_pair(root, false)); while (!stack.empty()) { pair<TreeNode*, bool>& pn = stack.back(); TreeNode* n = pn.first; if (pn.second) { stack.pop_back(); res.push_back(n->val); if (n->right != NULL) { stack.push_back(make_pair(n->right, false)); } continue; } pn.second = true; n = n->left; while (n != NULL) { stack.push_back(make_pair(n, true)); n = n->left; } } } // a better one vector<int> _inorderTraversal(TreeNode *root) { vector<int> res; vector<TreeNode*> stack; while(root != NULL || !stack.empty()) { while (root != NULL) { stack.push_back(root); root=root->left; } if (!stack.empty()) { root = stack.back(); stack.pop_back(); res.push_back(root->val); root = root->right; } } } };
这种题想想简单,写起来也不好写,尤其是写的像第二个那么巧妙简洁,又找到一个比较通用的可以用在中序遍历和后续遍历中
class Solution { public: vector<int> inorderTraversal(TreeNode *root) { vector<int> res; if (root == NULL) return res; vector<pair<TreeNode*, bool> > stack; stack.push_back(make_pair(root, false)); while (!stack.empty()) { pair<TreeNode*, bool>& pn = stack.back(); TreeNode* n = pn.first; stack.pop_back(); if (pn.second) { res.push_back(n->val); } else { if (n->right != NULL) { stack.push_back(make_pair(n->right, false)); } stack.push_back(make_pair(n, true)); if (n->left != NULL) { stack.push_back(make_pair(n->left, false)); } } } return res; } };
不过以上花样百出,以前好几次都写过但又记不起来(当然能直接想出来的也就没必要看了),现在应该有个终极方法将这些问题统统秒杀掉,以防止其再来迫害人类。因为递归实质上是用到了栈,通过循环加上一个自己维护的栈也可以模拟递归的过程。除了保存在栈上的一般可编程变量外,在函数调用的时候会还会把下一条语句(指令)的CS:EIP存入栈中作为返回地址一般的递归函数返回后,会从调用位置的下一条语句(指令)再开始执行,这个学过汇编就应该非常明白。我们可以通过一个变量再结合switch语句简单而低效的实现这个过程,实质上是个状态机。下面来看代码
vector<int> universal_traversal(TreeNode *root, int* map) { vector<int> res; vector<pair<TreeNode*, int> > stack; stack.push_back(make_pair(root, -1)); while (!stack.empty()) { pair<TreeNode*, int>& np = stack.back(); TreeNode* n = np.first; if (n == NULL) { stack.pop_back(); continue; } np.second++; switch(map[np.second]) { case 0: res.push_back(n->val);break; case 1: stack.push_back(make_pair(n->left, -1));break; case 2: stack.push_back(make_pair(n->right, -1));break; default:stack.pop_back(); } } return res; } void print(vector<int> nums) { for (int i=0; i<nums.size(); i++) { cout<<nums[i]<<" "; } cout<<endl; } int main() { TreeNode nodes[10]; for (int i=0; i<10; i++) { nodes[i].val = i; nodes[i].left = NULL; nodes[i].right = NULL; } nodes[0].left = &nodes[1]; // nodes[0].right= &nodes[2]; nodes[1].right = &nodes[3]; // nodes[1].right= &nodes[4]; int preorder[] = {0, 1, 2, -1}; int inorder[] = {1, 0, 2, -1}; int postorder[]= {1, 2, 0, -1}; cout<<"Preorder: "<<endl; print(universal_traversal(&nodes[0], preorder)); cout<<"Inorder: "<<endl; print(universal_traversal(&nodes[0], inorder)); cout<<"Postorder: "<<endl; print(universal_traversal(&nodes[0], postorder)); system("pause"); return 0; }
switch中的语句被函数中的map数组进行了映射,相当于几行代码重新排序了一下,因为树遍历重要的就三个语句(输出当前节点数据,左子树进栈,右子树进栈),通过不同的map数组映射,就分别得到了前序、中序、后序遍历的效果,从此妈妈再也不用担心我的学习!
第二轮:
Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [1,3,2]
.
Note: Recursive solution is trivial, could you do it iteratively?
还是先用经典方法做吧:
1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> inorderTraversal(TreeNode *root) { 13 vector<int> res; 14 if (root == NULL) { 15 return res; 16 } 17 18 vector<TreeNode*> stk; 19 TreeNode* cur = root; 20 while (cur != NULL) { 21 while (cur != NULL) { 22 stk.push_back(cur); 23 cur = cur->left; 24 } 25 while (!stk.empty()) { 26 cur = stk.back(); 27 res.push_back(cur->val); 28 stk.pop_back(); 29 if (cur->right != NULL) { 30 break; 31 } 32 } 33 34 cur = cur->right; 35 } 36 return res; 37 } 38 };
简洁一点:
/** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * TreeNode(int val) { * this->val = val; * this->left = this->right = NULL; * } * } */ class Solution { /** * @param root: The root of binary tree. * @return: Inorder in vector which contains node values. */ public: vector<int> inorderTraversal(TreeNode *root) { // write your code here vector<int> res; stack<TreeNode*> ns; TreeNode* curr = root; for (;;) { while (curr != NULL) { ns.push(curr); curr = curr->left; } if (ns.empty()) { break; } TreeNode* tmp = ns.top(); res.push_back(tmp->val); curr = tmp->right; ns.pop(); } return res; } };