Tranversal Binary Tree In Order
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?
思路:递归和非递归的版本都应该会,非递归的版本需要使用到stack,不是O(1)的空间。而O(1)的空间是用了Morris的方法,和Threading结合起来,第一遍先进行中序Threading,第二遍进行UnThreading
class Solution { public: vector<int> inorderTraversal(TreeNode *root) { vector<int> ans; if (!root){ return ans; } TreeNode * current = root; while(current){ if (!current->left){ //叶节点都得用这种方式访问 ans.push_back(current->val); current = current->right; //因为这个指针已经threading,所以将来不怕right为空的情况。也可能只指向真右子树,也有可能是当前子树的根节点 }else{ TreeNode * p = current->left; while(p->right && p->right != current){ p = p->right; } if (!p->right){ //threading first time p->right = current; current = current->left; }else{ //unthreading second time access it //这种情况只是不想破坏原来二叉树的结构,要不然可以直接访问current节点,而不用再过一遍 ans.push_back(current->val); p->right = NULL; current = current->right; } } } } };
顺手写一个O(1)空间复杂度的PreOrder的Morris的版本
class Solution { public: vector<int> PreorderTraversalMorris(TreeNode *root) { vector<int> ans; if (!root){ return ans; } TreeNode * current = root; while(current){ if (!current->left){ //叶节点都得用这种方式访问 //无论是InOrder还是PreOrder,这个节点都需要访问了 要么是叶节点 要么是没有左子树 ans.push_back(current->val); current = current->right; //因为这个指针已经threading,所以将来不怕right为空的情况 }else{ TreeNode * p = current->left; while(p->right && p->right != current){ p = p->right; } if (!p->right){ //threading first time p->right = current; //如果是preOder的话,第一遍下来的时候就需要访问 //第二遍unthreading的时候,就不需要访问了 ans.push_back(current->val); current = current->left; }else{ //unthreading second time access it //这种情况只是不想破坏原来二叉树的结构,要不然可以直接访问current节点,而不用再过一遍 //ans.push_back(current->val); //PreOrder的话,那么要转到右边去,就不需要访问了 p->right = NULL; current = current->right; } } } } };