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

 

 

posted @ 2014-03-21 12:53  卖程序的小歪  阅读(218)  评论(0编辑  收藏  举报