刷题打卡day 14 二叉树: 递归遍历 、 迭代遍历、统一迭代

迭代遍历没有特别看懂,准备慢慢看,这里先把递归遍历整理总结一下,打卡:

以下均参考代码随想录。

递归遍历:

每次写递归,都按照这三要素来写:

  1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。

  2. 确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。

  3. 确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

以下以前序遍历为例:

确定递归函数的参数和返回值:因为要打印出前序遍历节点的数值,所以参数里需要传入vector来放节点的数值,除了这一点就不需要再处理什么数据了也不需要有返回值,所以递归函数返回类型就是void,代码如下:

void traversal(TreeNode* cur, vector<int>& vec)

确定终止条件:在递归的过程中,如何算是递归结束了呢,当然是当前遍历的节点是空了,那么本层递归就要结束了,所以如果当前遍历的这个节点是空,就直接return,代码如下:

if (cur == NULL) return;

确定单层递归的逻辑:前序遍历是中左右的循序,所以在单层递归的逻辑,是要先取中节点的数值,代码如下:

vec.push_back(cur->val);    // 中
traversal(cur->left, vec);  // 左
traversal(cur->right, vec); // 右

 

具体代码:

前序遍历:

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == NULL) return;
        vec.push_back(cur->val);    // 中
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

中序遍历:

void traversal(TreeNode* cur, vector<int>& vec) {
    if (cur == NULL) return;
    traversal(cur->left, vec);  // 左
    vec.push_back(cur->val);    // 中
    traversal(cur->right, vec); // 右
}

后序遍历:

void traversal(TreeNode* cur, vector<int>& vec) {
    if (cur == NULL) return;
    traversal(cur->left, vec);  // 左
    traversal(cur->right, vec); // 右
    vec.push_back(cur->val);    // 中
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
叉树的遍有三种方式:前序遍、中序遍和后序遍。其中,归遍是比较常见的方式,而非归遍则需要借助栈的数据结构实现。 下面给出二叉树归遍和非归遍的C语言代码实现: 1. 二叉树归遍 前序遍: ``` void preorderTraversal(TreeNode* root) { if (root == NULL) { return; } printf("%d ", root->val); // 访问根节点 preorderTraversal(root->left); // 归遍左子树 preorderTraversal(root->right); // 归遍右子树 } ``` 中序遍: ``` void inorderTraversal(TreeNode* root) { if (root == NULL) { return; } inorderTraversal(root->left); // 归遍左子树 printf("%d ", root->val); // 访问根节点 inorderTraversal(root->right); // 归遍右子树 } ``` 后序遍: ``` void postorderTraversal(TreeNode* root) { if (root == NULL) { return; } postorderTraversal(root->left); // 归遍左子树 postorderTraversal(root->right); // 归遍右子树 printf("%d ", root->val); // 访问根节点 } ``` 2. 二叉树的非归遍 前序遍: ``` void preorderTraversal(TreeNode* root) { if (root == NULL) { return; } stack<TreeNode*> st; st.push(root); while (!st.empty()) { TreeNode* node = st.top(); st.pop(); printf("%d ", node->val); // 访问节点 if (node->right != NULL) { st.push(node->right); // 右子节点先入栈,保证左子节点先出栈 } if (node->left != NULL) { st.push(node->left); } } } ``` 中序遍: ``` void inorderTraversal(TreeNode* root) { stack<TreeNode*> st; TreeNode* node = root; while (!st.empty() || node != NULL) { if (node != NULL) { // 当前节点不为空,继续将其左子节点入栈 st.push(node); node = node->left; } else { // 当前节点为空,说明已经到达最左侧,开始出栈访问节点 node = st.top(); st.pop(); printf("%d ", node->val); // 访问节点 node = node->right; // 开始访问右子节点 } } } ``` 后序遍: ``` void postorderTraversal(TreeNode* root) { if (root == NULL) { return; } stack<TreeNode*> st1, st2; st1.push(root); while (!st1.empty()) { TreeNode* node = st1.top(); st1.pop(); st2.push(node); // 先将当前节点入栈st2 if (node->left != NULL) { st1.push(node->left); // 左子节点入栈st1 } if (node->right != NULL) { st1.push(node->right); // 右子节点入栈st1 } } while (!st2.empty()) { // 出栈访问节点 TreeNode* node = st2.top(); st2.pop(); printf("%d ", node->val); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值