zoukankan      html  css  js  c++  java
  • 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;
        }
    };
  • 相关阅读:
    9ch
    thymeleaf 的使用(三)--举例使用
    thymeleaf 的使用(二)--基本语法
    thymeleaf 的使用(一)--导入和基本操作
    SpringBoot对静态资源的映射规则
    第一个Spring Boot项目
    HTML文本换行问题
    判断for(var i=0;i<=3;i++){ setTimeout(function() { console.log(i) }, 10) }
    js的执行机制——宏任务和微任务
    v-if 和 v-show 的区别
  • 原文地址:https://www.cnblogs.com/lailailai/p/3615605.html
Copyright © 2011-2022 走看看