zoukankan      html  css  js  c++  java
  • Binary Tree Preorder Traversal -- leetcode

    Given a binary tree, return the preorder traversal of its nodes' values.

    For example:
    Given binary tree {1,#,2,3},

       1
        
         2
        /
       3
    

    return [1,2,3].

    Note: Recursive solution is trivial, could you do it iteratively?


    算法一,栈

    前序遍历。

    1.訪问根结点

    2.訪问左子树

    3.訪问右子树

    题目要求不使用递归。

    此处使用栈实现。

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<int> preorderTraversal(TreeNode* root) {
            vector<int> ans;
            if (!root)
                return ans;
            stack<TreeNode *> s;
            s.push(root);
            while (!s.empty()) {
                root = s.top();
                s.pop();
                ans.push_back(root->val);
                if (root->right)
                    s.push(root->right);
                if (root->left)
                    s.push(root->left);
            }
            return ans;
        }
    };


    算法二,栈保存右子树结点。

    和上面差别是,此处用栈仅仅保留右孩子结点。

    算法一。事实上左孩子循环结束时刚刚入栈了,下次循环開始时,立刻又会出栈。

    在此实现中。则直接用一变量保存左孩子。不必进栈出栈。


    class Solution {
    public:
        vector<int> preorderTraversal(TreeNode* root) {
            vector<int> ans;
            stack<TreeNode *> rights;
            while (root || !rights.empty()) {
                if (root) {
                    ans.push_back(root->val);
                    rights.push(root->right);
                    root = root->left;
                }
                else {
                    root = rights.top();
                    rights.pop();
                }
            }
            return ans;
        }
    };


    算法三,线索遍历

    不再使用栈。而使用节点中空暇的右指针。让其指向根结点。

    訪问一个左子树之前。先找到其左子树最右下的孩子,让其右指针指向根结点。

    以便在訪问完左子树后。能返回根结点。从而找到根结点的右子树。

    即訪问左子树之前,须要先建立返回的线索。

    要注意的是。在建立线索的情况下,在訪问一个结点时,假设其左子树不空。 

    则此时,包括两种情况:

    1. 此结点未訪问过。

    2. 此结点已经訪问过。即訪问完左孩子,刚延着线索返回来。

    怎样区分上面两种情况。就是看左子树的返回线索是否已经建立。


    class Solution {
    public:
        vector<int> preorderTraversal(TreeNode* root) {
            vector<int> ans;
            while (root) {
                if (!root->left) {
                    ans.push_back(root->val);
                    root = root->right;
                }
                else {
                    TreeNode *runner = root->left;
                    while (runner->right && runner->right != root)
                        runner = runner->right;
                    
                    if (!runner->right) {
                        ans.push_back(root->val);
                        runner->right = root;
                        root = root->left;
                    }
                    else {
                        runner->right = NULL;
                        root = root->right;
                    }
                }
            }
            return ans;
        }
    };


  • 相关阅读:
    Linux:CentOS-7配置VMware-15.5与本机IP同网段
    SpringCloud:Zuul路由配置超时问题
    SpringCloud:路由ZUUL的配置详解
    SpringCloud:扩展zuul配置路由访问
    给source insight添加.cc的C++文件后缀识别(转载)
    Linux下共享库嵌套依赖问题 (转载)
    Ubuntu 下编译libjingle-0.6.14 (转载)
    什么是「穷人思维」?
    谁上北大是能力说了算,不该是教育部(转载)
    Installing cmake 2.8.8 or higher on Ubuntu 12.04 (Precise Pangolin) (转载)
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/7286890.html
Copyright © 2011-2022 走看看