算法学习打卡day13 | 二叉树的遍历(前、中、后序、层次)

二叉树遍历递归法

前序遍历力扣题目链接中序遍历力扣题目链接后序遍历力扣题目链接

思路:

  • 递归法很简单,三部曲:
    1. 确定函数参数和返回值:参数为二叉树节点和结果集,返回值为空
    2. 确定递归退出条件:当节点为空时退出
    3. 确定单层逻辑:前序遍历是中左右的循序,中序遍历是左中右,后序遍历是左右中,所以前序遍历在单层递归的逻辑,是要先取中节点的数值,然后分别递归左孩子和右孩子,剩下两个对应写就行。

代码实现:

  • 前序遍历

void Traversal(TreeNode* root, vector<int>& vec) {
     if (root == nullptr) {
         return;
     }
     vec.push_back(root->val);
     Traversal(root->left, vec);
     Traversal(root->right, vec);
     return;
 }
vector<int> preorderTraversal(TreeNode* root) {
     vector<int> results;
     Traversal(root, results);
     return results;
 }
  • 中序遍历
void traversal(TreeNode* cur, vector<int>& vec) {
    if (root == nullptr) {
         return;
     }
    traversal(cur->left, vec);  // 左
    vec.push_back(cur->val);    // 中
    traversal(cur->right, vec); // 右
}
vector<int> inorderTraversal(TreeNode* root) {
	vector<int> results;
    Traversal(root, results);
    return results;
}
  • 后序遍历
void Traversal(TreeNode* root, vector<int>& vec) {
     if (root == nullptr) {
         return;
     }
     Traversal(root->left, vec);
     Traversal(root->right, vec);
     vec.push_back(root->val);
     return;
 }
vector<int> postorderTraversal(TreeNode* root) {
	vector<int> results;
    Traversal(root, results);
    return results;
}

二叉树遍历迭代法

前序遍历

思路

  • 借助栈来模拟中左右的遍历过程,但是注意要先将右孩子节点存入栈中。
    在这里插入图片描述

代码实现

vector<int> preorderTraversal(TreeNode* root) {
        if (root == nullptr) {
            return {};
        }
        stack<TreeNode*> stk;
        vector<int> results;
        stk.push(root);
        while(!stk.empty()) {
            TreeNode* cur = stk.top();
            stk.pop();
            results.push_back(cur->val);
            if(cur->right) stk.push(cur->right);
            if(cur->left)   stk.push(cur->left);
        }
        return results;
    }
中序遍历

思路

  • 同样借助栈来模拟左中右的遍历过程,但是和前序遍历略有不同,我们需要先找到左子树最大深度的左节点才能处理,所以处理(将元素放入结果集中)和访问(遍历二叉树)不是同时进行的,而前序遍历是中左右,那么处理和访问是同时进行的,因此需要借助指针来去访问,借助栈来处理。
    在这里插入图片描述

代码实现

vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) { // 指针来访问节点,访问到最底层
                st.push(cur); // 将访问的节点放进栈
                cur = cur->left;                // 左
            } else {
                cur = st.top(); // 从栈里弹出的数据,就是要处理的数据(放进result数组里的数据)
                st.pop();
                result.push_back(cur->val);     // 中
                cur = cur->right;               // 右
            }
        }
        return result;
    }
后序遍历

思路

  • 方法一:前序遍历是右左的压栈顺序,得到的结果是中左右,而我们将前序的压栈顺序换成左右,得到的结果是中右左,然后将结果集反转即可。
  • 方法二:借助两个栈,循环条件是判断第一个栈非空,第一个栈按左右的顺序压栈,那么出栈顺序为右左,然后第二个栈存放根节点,最后得到的第二个栈整体是中右左的顺序,然后遍历第二个栈,依次出栈存到数组即为左右中的顺序。

代码实现:

  • 方法一
vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> result;
        if (root == NULL) return result;
        st.push(root);
        while (!st.empty()) {
            TreeNode* node = st.top();
            st.pop();
            result.push_back(node->val);
            if (node->left) st.push(node->left); // 相对于前序遍历,这更改一下入栈顺序 (空节点不入栈)
            if (node->right) st.push(node->right); // 空节点不入栈
        }
        reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序了
        return result;
    }
  • 方法二
vector<int> postorderTraversal(TreeNode* root) {
        if(root == nullptr)
            return {};
        stack<TreeNode*> stk;
        stack<TreeNode*> stk1;
        stk.push(root);
        while(!stk.empty()) {
            TreeNode* node = stk.top();
            stk.pop();
            if(node->left)	stk.push(node->left);
            if(node->right)	stk.push(node->right);
            stk1.push(node);
        }
        while(!stk1.empty()) {
            vec.push_back(stk1.top()->val);
            stk1.pop();
        }
        return vec;
    }

层次遍历

力扣题目链接
题目描述:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
思路:

  • 其实是图的广度优先遍历,借助队列一列一列模拟即可。

代码实现

vector<vector<int>> levelOrder(TreeNode* root) { 
        queue<TreeNode*> que;
        vector<vector<int>> results;
        int size = 0;
        if (root != nullptr) {
            que.push(root);
        }     
        while(!que.empty()) {
            size = que.size();
            vector<int> vec;
            for(int i = 0; i < size; i++) {
                TreeNode* cur = que.front();
                que.pop();
                vec.push_back(cur->val);
                if (cur->left) que.push(cur->left);
                if (cur->right) que.push(cur->right);
            }
            results.push_back(vec);
        }
        return results;
    }
  • BFS递归法遍历
在这里插入代码片
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值