LeetCode刷题笔记 94. 二叉树的中序遍历

题目要求

给定一个二叉树,返回它的中序 遍历。

示例:

输入: [1,null,2,3]
   1
    \
     2
    /
   3

输出: [1,3,2]

题解

https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/die-dai-fa-by-jason-2/

关于后序遍历的第二种方法我理解的不是很好,所以采用笨比法认真理解了一遍,感觉理解的不太好又不巧有耐心的读者可以对比着看一下:
为了让注释看得清楚一点,我就用单引号了。

原代码

class Solution {
public:
        vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> S;
        unordered_map<TreeNode*,int> done;
        vector<int> v;
        TreeNode* rt = root;
        while(rt || S.size()){
        	/ @1
            while(rt){
            	/ @2
                S.push(rt);
                rt=rt->left;
            }
            / cout<<S.top()->val<<" XXX "<<done[S.top()]<<endl
            while(S.size() && done[S.top()]){
            	/ @3
                v.push_back(S.top()->val);
                S.pop();
            }
            if(S.size()){
                rt=S.top()->right;
                / @4
                done[S.top()]=1;    
            }
        }
        return v;
    }
};

Playground代码

class Solution {
public:
        vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> S;
        unordered_map<TreeNode*,int> done;
        vector<int> v;
        TreeNode* rt = root;
        while(rt || S.size()){
            prettyPrintTree(rt);
            cout<<"@1    "<<endl;
            while(rt){
                prettyPrintTree(rt);
                cout<<"@2    "<<endl;
                S.push(rt);
                rt=rt->left;
            }
            cout<<S.top()->val<<" XXX "<<done[S.top()]<<endl;
            while(S.size() && done[S.top()]){
                cout<<"@3    "<<done[S.top()]<<endl;
                v.push_back(S.top()->val);
                S.pop();
            }
            if(S.size()){
                rt=S.top()->right;
                cout<<"@4    "<<endl;
                done[S.top()]=1;    
            }
        }
        return v;
    }
};

输出结果

│       ┌── 7
│   ┌── 3
│   │   └── 6
└── 1
    │   ┌── 5
    └── 2
        └── 4
@1    
│       ┌── 7
│   ┌── 3
│   │   └── 6
└── 1
    │   ┌── 5
    └── 2
        └── 4
@2    
│   ┌── 5
└── 2
    └── 4
@2    
└── 4
@2    
4 XXX 0
@4    
Empty tree@1    
4 XXX 1
@3    1
@4    
└── 5
@1    
└── 5
@2    
5 XXX 0
@4    
Empty tree@1    
5 XXX 1
@3    1
@3    1
@4    
│   ┌── 7
└── 3
    └── 6
@1    
│   ┌── 7
└── 3
    └── 6
@2    
└── 6
@2    
6 XXX 0
@4    
Empty tree@1    
6 XXX 1
@3    1
@4    
└── 7
@1    
└── 7
@2    
7 XXX 0
@4    
Empty tree@1    
7 XXX 1
@3    1
@3    1
@3    1
[4, 5, 2, 6, 7, 3, 1]

顺便再稍微注释一下。

class Solution {
public:
        vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> S;
        unordered_map<TreeNode*,int> done; / 用unordered_map来储存节点是否被遍历过了
        vector<int> v;
        TreeNode* rt = root;
        while(rt || S.size()){
        	/ 找到最左节点
            while(rt){
                S.push(rt);
                rt=rt->left;  
            }
            / 第一轮是跳过这个部分的,直到确定已经遍历完了最左节点之后(done[S.top()]=1)才进入循环
            while(S.size() && done[S.top()]){
                v.push_back(S.top()->val);
                S.pop();
            }
            / 当前S.top()的左子树已经遍历完,准备转向右子树,并准备输出中间节点。
            if(S.size()){
                rt=S.top()->right;
                done[S.top()]=1;    
            }
        }
        return v;
    }
};
发布了18 篇原创文章 · 获赞 0 · 访问量 1788

猜你喜欢

转载自blog.csdn.net/g534441921/article/details/104186382