中序遍历二叉树

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

/**
 * 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;
    }
};
    原文作者:Bird_S_Yellow
    原文地址: https://www.jianshu.com/p/5aab6f915daa
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞