美文网首页
中序遍历二叉树

中序遍历二叉树

作者: 衣忌破 | 来源:发表于2017-05-09 11:47 被阅读20次

    以下是使用递归实现中序遍历的算法:

    /**
     * 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> inorderTraversal(TreeNode* root) {
            vector<int> vec;
            return traver(root, vec);
        }
        
        vector<int> traver(TreeNode* root, vector<int>& vec){        
            if(!root){
                return vec;
            }
            traver(root->left, vec);
            vec.push_back(root->val);       
            traver(root->right, vec);
            return vec;
        }
    };
    

    不使用递归的实现思路

    算法1、2:

    1. 通过循环获取根节点root的左子点,得到以root为根节点的树中最左的节点,循环期间所有节点依次进栈直至“最左节点”进栈。
    2. 当"最左节点"进栈后,栈顶节点的值放进vector中,然后判断弹出栈顶节点并判断是否有右子节点,如果右子节点不为空,则以该右子节点为根节点执行1)

    算法3 :

    相较与1、2该算法更为巧妙简介
    思路跟1、2大体相同,当在while循环体中,不需要每次都去获取栈顶节点,通过判断pCurrent是否为空对“左节点进栈”的同时也避免了重复遍历的情况。

    1 使用栈去实现,但算法执行后树会发生改变

    class Solution {
    public:
        vector<int> inorderTraversal(TreeNode *root) {
            vector<int> vector;
            if(!root)
            return vector;
            stack<TreeNode *> stack;
            stack.push(root);
            while(!stack.empty())
            {
                TreeNode *pNode = stack.top();
                if(pNode->left)
                {
                    stack.push(pNode->left);
                    pNode->left = NULL;//放置重复遍历
                }
                else
                {
                    vector.push_back(pNode->val);
                    stack.pop();
                    if(pNode->right)
                            stack.push(pNode->right);
                }
            }
            return vector;
        }
    };
    

    2 使用unordered_map和栈,算法执行后tree不会发生改变

    class Solution {
    public:
        vector<int> inorderTraversal(TreeNode *root) {
            vector<int> vector;
            if(!root)
            return vector;
            unordered_map<TreeNode *, bool> map;//left child has been visited:true.
            stack<TreeNode *> stack;
            stack.push(root);
            while(!stack.empty())
            {
                TreeNode *pNode = stack.top();
                if(pNode->left && !map[pNode])//防止重复遍历
                {
                    stack.push(pNode->left);
                    map[pNode] = true;
                }
                else
                {
                    vector.push_back(pNode->val);
                    stack.pop();
                    if(pNode->right)
                    stack.push(pNode->right);
                }
            }
            return vector;
        }
    };
    

    3 只使用一个栈但树的不会发生改变

    class Solution {
    public:
        vector<int> inorderTraversal(TreeNode *root) {
            vector<int> vector;
            stack<TreeNode *> stack;
            TreeNode *pCurrent = root;
            
            while(!stack.empty() || pCurrent)
            {
                if(pCurrent)
                {
                    //同一根节点下的左右节点,左节点比右节点先出栈(即左节点后进栈,其实最后所有进栈的节点都可以视左一个树中的中间节点。)
                    stack.push(pCurrent);
                    pCurrent = pCurrent->left;//若左节点为空则,该节点可以等同为中间节点,相对于其右节点先出栈(后进栈)
                }//节点为空就出栈
                else
                {//当节点出栈后,还需要判断是否有右子节点
                    TreeNode *pNode = stack.top();
                    vector.push_back(pNode->val);
                    stack.pop();
                    pCurrent = pNode->right;
                }
            }
            return vector;
        }
    };
    

    相关文章

      网友评论

          本文标题:中序遍历二叉树

          本文链接:https://www.haomeiwen.com/subject/xsmbtxtx.html