二叉树遍历方法

二叉树遍历:先序遍历、中序遍历和后序遍历

二叉树结构:

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

一、先序遍历

1.常规方法,通过递归实现

class Solution {
public:
    vector<int> preorderTraversal(TreeNode *root) {
        vector<int> result;
        preorderRecusion(root, result);
        return result;
    }

    void preorderRecusion(TreeNode *root, vector<int> &result)
    {
        if (root!=NULL)
        {
            result.push_back(root->val);
            preorderRecusion(root->left, result);
            preorderRecusion(root->right, result);
        }
    }
};

2. 非递归,通过栈实现

class Solution
{
public:
    vector<int> preorderTraversal(TreeNode *root) {
        vector<int> result;
        preorderStack(root, result);
        return result;
    }

    void preorderStack(TreeNode *root, vector<int> &result)
    {
        if (root==NULL)
        {
            return;
        }
        stack<TreeNode*> st;
        st.push(root);
        while(!st.empty())
        {
            TreeNode *cur = st.top();
            st.pop();
            result.push_back(cur->val);
            if (cur->right)
            {
                st.push(cur->right);
            }
            if (cur->left)
            {
                st.push(cur->left);
            }
        }
    }
};

二、中序遍历

1.常规方法,通过递归实现

class Solution {
public:
    vector<int> inorderTraversal(TreeNode *root) {
        vector<int> result;
        inorderRecusion(root, result);
        return result;
    }

    void inorderRecusion(TreeNode *root, vector<int> &result)
    {
        if (root!=NULL)
        {
            inorderRecusion(root->left, result);
            result.push_back(root->val);
            inorderRecusion(root->right, result);
        }
    }
};

2. 非递归,通过栈实现

class Solution {
public:
    vector<int> inorderTraversal(TreeNode *root) {
        vector<int> result;
        inorderStack(root, result);
        return result;
    }

    void inorderStack(TreeNode *root, vector<int> &result)
    {
        stack<TreeNode*> st;
        TreeNode *next = root;
        while(next || !st.empty())
        {
            if (next)
            {
                st.push(next);
                next = next->left;
            }
            else
            {
                next = st.top();
                st.pop();
                result.push_back(next->val);
                next = next->right;
            }
        }
    }
};

三、后序遍历

1.常规方法,通过递归实现

class Solution {
public:
    vector<int> postorderTraversal(TreeNode *root) {
        vector<int> result;
        postorderRecusion(root, result);
        return result;
    }

    void postorderRecusion(TreeNode *root, vector<int> &result)
    {
        if (root!=NULL)
        {
            postorderRecusion(root->left, result);
            postorderRecusion(root->right, result);
            result.push_back(root->val);
        }
    }
};

2. 非递归,通过栈实现

2.1:发现:先序.reverse = 右左中,因而右左交换就得到左右中,即将原来的先序变通下就有了下面的算法.

class Solution
{
public:
    vector<int> postorderTraversal(TreeNode *root) {
        vector<int> result;
        postorderStack(root, result);
        return result;
    }

    void postorderStack(TreeNode *root, vector<int> &result)
    {
        if (root==NULL)
        {
            return ;
        }
        stack<TreeNode*> st;
        st.push(root);
        while(!st.empty())
        {
            TreeNode *cur = st.top();
            st.pop();
            result.push_back(cur->val);
            if (cur->left)
            {
                st.push(cur->left);
            }
            if (cur->right)
            {
                st.push(cur->right);
            }
        }
        std::reverse(result.begin(), result.end());
    }
};

2.2:传统方法

说明:要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。
如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。

class Solution
{
public:
    vector<int> postorderTraversal(TreeNode *root) {
        vector<int> result;
        postorderStack(root, result);
        return result;
    }

    void postorderStack(TreeNode *root, vector<int> &result)
    {
        if (root==NULL)
        {
            return ;
        }
        stack<TreeNode*> st;
        TreeNode * last = NULL;
        st.push(root);
        while(!st.empty())
        {
            TreeNode *cur = st.top();
            if ((cur->left==NULL && cur->right==NULL) || last && (cur->right==last || cur->left==last))
            {
                st.pop();
                result.push_back(cur->val);
                last = cur;
            }
            else
            {
                if (cur->right)
                {
                    st.push(cur->right);
                }
                if (cur->left)
                {
                    st.push(cur->left);
                }
            }
        }
    }
};
posted @ 2015-04-03 23:01  bestyang  阅读(155)  评论(0)    收藏  举报