前序遍历

二叉树结构

-前序遍历结果:1-2-4-5-6-7-3-8-9

递归遍历

1
2
3
4
5
void pre(TreeNode* root,vector<int> &res){
res.push_back(root->val);
pre(root->left,res);
pre(root->right,res);
}

迭代(非递归)遍历

思路一:

步骤(思路):
1. 沿着根的左孩子,依次入栈并访问,直到左孩子为空
2. 栈顶元素出栈
若其右孩子为空,继续步骤2;
若右孩子不空,将右子树执行步骤1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
vector<int> preorderTraversal(TreeNode* root) {
        if(!root)
            return {};
        vector<int> res;
        stack<TreeNode*> mystack;
        TreeNode* temp=root;
        //沿着根的左孩子,依次入栈并访问,直到左孩子为空
        while(temp){
            mystack.push(temp);
            res.push_back(temp->val);
            temp=temp->left;
        }
       
        while(mystack.size()){
        //栈顶元素出栈
            temp=mystack.top();
            mystack.pop();
            //若右孩子不空,将右子树执行步骤1
            //若其右孩子为空,继续步骤2(继续循环)
            temp=temp->right;
            while(temp){
                mystack.push(temp);
                res.push_back(temp->val);
                temp=temp->left;
            }
        }
        return res;

    }

思路二:

步骤(思路):
1. 将根压入栈中;
2. 栈顶元素出栈并访问
先右后左,将孩子依次压入栈中。
重复步骤一直至栈为空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
vector<int> preorderTraversal(TreeNode* root) {
        if(!root)
            return {};
        vector<int> res;
        stack<TreeNode*> mystack;
        mystack.push(root);
        TreeNode* temp;
        while(mystack.size()){
            temp=mystack.top();
            mystack.pop();
            res.push_back(temp->val);
            if(temp->right){
                mystack.push(temp->right);
            }
            if(temp->left){
                mystack.push(temp->left);
            }
        }
        return res;
    }

中序遍历

-中序遍历结果:4-2-6-5-7-1-3-9-8

递归遍历

1
2
3
4
5
6
void mid(TreeNode* root,vector<int> &res){

mid(root->left,res);
res.push_back(root->val);
mid(root->right,res);
}

迭代(非递归)遍历

步骤(思路):
1. 沿着根的左孩子,依次入栈,直到左孩子为空
2. 栈顶元素出栈并访问
若其右孩子为空,继续步骤2;
若右孩子不空,将右子树执行步骤1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
vector<int> inorderTraversal(TreeNode* root) {
        if(!root)
            return {};
        vector<int> res;
        stack<TreeNode*> mystack;
        TreeNode* temp=root;
        //沿着根的左孩子,依次入栈,直到左孩子为空
        while(temp){
            mystack.push(temp);
            temp=temp->left;
        }
       
        while(mystack.size()){
        //栈顶元素出栈并访问
            temp=mystack.top();
            mystack.pop();
            res.push_back(temp->val);
            //若右孩子不空,将右子树执行步骤1
            //若其右孩子为空,继续步骤2(继续循环)
            temp=temp->right;
            while(temp){
                mystack.push(temp);
                temp=temp->left;
            }
        }
        return res;

    }

注意到:该实现与前序遍历的迭代遍历中思路一高度相似:按照先序序列进栈,出栈的序列一定是一个中序序列(该结论必定正确,帮助记忆前序遍历与中序遍历,但是不需要证明)

后序遍历

-后序遍历结果:4-6-7-5-2-9-8-3-1

递归遍历

1
2
3
4
5
6
void postorder(TreeNode* root,vector<int> &res){

postorder(root->left,res);
postorder(root->right,res);
res.push_back(root->val);
}

迭代(非递归)遍历

步骤(思路):
1. 沿着根的左孩子,依次入栈,直到左孩子为空
2.扫描栈顶元素:
若无右孩子,弹出并访问,修改辅助指针
若有右孩子:
右孩子未被访问过,将右孩子视为根节点执行步骤一。
右孩子已被访问过,不再访问右孩子。
利用一个辅助指针记录上一个被访问的结点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> mystack;
        TreeNode *temp, *last;
        temp = root;
        last = nullptr;
        while (temp) {
            mystack.push(temp);
            temp = temp->left;
        }
        while (mystack.size()) {
            temp = mystack.top();
            if (!temp->right) {
                mystack.pop();
                last = temp;
                res.push_back(temp->val);
            } else {
                if (temp->right == last) {
                    mystack.pop();
                    last = temp;
                    res.push_back(temp->val);
                } else {
                    temp = temp->right;
                    while (temp) {
                        mystack.push(temp);
                        temp = temp->left;
                    }
                }
            }
        }
        return res;
    }