题解 | #易理解的二叉树不同顺序遍历的迭代统一实现#

实现二叉树先序,中序和后序遍历

https://www.nowcoder.com/practice/a9fec6c46a684ad5a3abd4e365a9d362

在考虑二叉树的深度优先遍历问题时(包括前序、中序、后序遍历),递归方法是最清晰易理解且好实现的一种,但考虑到递归算法的效率,通常不推荐使用递归。

利用栈辅助实现的迭代方法提高了遍历算法的效率,但嵌套循环的方法看起来不易理解,写起来也容易出错。并且对于不同的遍历顺序,代码结构差异较大,更容易产生错误。

因此,为了使迭代实现不仅高效,而且能够像递归方法一样简洁易理解,这里介绍一种迭代实现不同顺序遍历的统一写法,方便理解和记忆。

核心思路

其核心思路来源于这样一个结论:二叉树的不同顺序遍历过程中经过结点的路线一样,只是访问各结点的时机不同

  • 先序遍历:第1次遇到节点时访问,第1次遇到在“遍历”该节点的左子树之前;
  • 中序遍历:第2次遇到节点时访问,第2次遇到在“遍历”该节点的左子树之后,在”遍历“右子树之前;
  • 后序遍历:第3次遇到节点时访问,第3次遇到在“遍历”右子树之后。

注:“遍历”指沿下图中的路线经过。

因此在模拟系统栈的过程中,使用一个计数变量来记录结点入栈出栈的次数,以便能够根据不同的遍历顺序需要在合适的时机(先序:第1次遇见,中序:第2次,后续:第3次)访问结点。

具体的c++代码实现如下:

/**
 * struct TreeNode {
 *  int val;
 *  struct TreeNode *left;
 *  struct TreeNode *right;
 *  TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
  public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类 the root of binary tree
     * @return int整型vector<vector<>>
     */
    vector<vector<int> > threeOrders(TreeNode* root) {
        // write code here
        vector<int> preOrder, inOrder, postOrder;
        stack<pair<TreeNode*, int>> st;
        st.push(make_pair(root, 1));
        int cnt; //记录遇到结点的次数

        // 模拟系统栈的过程
        while (!st.empty()) {
            root = st.top().first;
            cnt = st.top().second;
            st.pop();
            if (!root)
                continue;
            if (cnt == 1) { // 第一次遇到结点,只会往其左孩子走
                preOrder.push_back(root->val);//前序遍历在第一次遇到结点时访问
                // 先将结点入栈,然后是其左孩子
                st.push(make_pair(root, 2));
                st.push(make_pair(root->left, 1));
            } 
            else if (cnt == 2) { // 第二次遇见结点,表示左孩子已经遍历完了,接下来遍历右孩子
                inOrder.push_back(root->val);//中序遍历在第二次遇到结点时访问
                st.push(make_pair(root, 3));
                st.push(make_pair(root->right, 1));
            } else { // 第三次遇到结点,表示以该结点为根的子树遍历完成
                postOrder.push_back(root->val);//后序遍历在第三次遇到结点时访问
            }
        }
        vector<vector<int> > res = {preOrder, inOrder, postOrder};
        return res;
    }
};
全部评论

相关推荐

04-28 22:33
已编辑
门头沟学院 C++
点赞 评论 收藏
分享
程序员牛肉:这一眼假啊,基本上都是骗人的,不然就涉及到职位贪腐了,就像之前华为的OD事件,看你运气好不好了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务