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;
                }
            }
        }
    }
};

 

 

posted @ 2013-06-11 16:27  一只会思考的猪  阅读(297)  评论(0编辑  收藏  举报