代码随想录算法训练营第十四天 | 二叉树理论基础、二叉树前中后序的递归遍历及迭代遍历

day_14

传送门


递归遍历

  • 前序
typedef struct TreeNode TreeNode;


void preOrder(TreeNode* root, int* ret, int* returnSize){
    if (root == NULL){
        return;
    }

    ret[(*returnSize)++] = root ->val;
    preOrder(root->left, ret, returnSize);
    preOrder(root->right, ret, returnSize);
}


int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int* ret = (int* )malloc(sizeof(int) * 100);
    *returnSize = 0;
    preOrder(root, ret, returnSize);

    return ret;
}
  • 中序
typedef struct TreeNode TreeNode;


void inorder(TreeNode* root, int* ret, int* returnSize){
    if (root == NULL){
        return;
    }

    if (root->left != NULL){
        inorder(root->left, ret, returnSize);
    }

    ret[(*returnSize)++] = root -> val;
    
    if (root->right != NULL){
        inorder(root->right, ret, returnSize);
    }
    
}


int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int* ret = (int* )malloc(sizeof(int)* 100);
    *returnSize = 0;
    inorder(root, ret, returnSize);

    return ret;
}
  • 后序
typedef struct TreeNode TreeNode;


void postOrder(TreeNode* root, int* ret, int* returnSize){
    if (root == NULL){
        return;
    }

    //  左
    if (root->left != NULL){
        postOrder(root->left, ret, returnSize);
    }

    //  右
    if (root->right != NULL){
        postOrder(root->right, ret, returnSize);
    }

    //  根节点
    ret[(*returnSize)++] = root -> val;
}


int* postorderTraversal(struct TreeNode* root, int* returnSize){
    int* ret = (int* )malloc(sizeof(int)* 100);
    *returnSize = 0;
    postOrder(root, ret, returnSize);
    return ret;
}

迭代遍历

  • 前序
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        List<Integer> ansList = new ArrayList<>();
        
        if (root == null){
            return ansList;
        }
        //  初始化栈
        stack.push(root);
        
        TreeNode cur = null;
        //  开始遍历,当栈不为空的时候,就一直遍历下去
        while (!stack.isEmpty()){
            cur = stack.pop();
            if (cur == null) continue;
            else {
                //  当前节点不为空的时候,先将该节点的数据放入 list 中,再将右左子节点入栈
                ansList.add(cur.val);
                if (cur.right != null) stack.push(cur.right);
                if (cur.left != null)   stack.push(cur.left);
            }
        }
        
        return ansList;
    }
}
  • 中序
    • 思路
      Push 非空的左子节点
      Pop  左子节点null时,pop父节点,右子节点为空的时候,pop父节点的父亲
      如何pop父亲的父亲呢?判断完左为 null, 先pop父亲,再转入右子节点,pop 父亲的父亲
    
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        List<Integer> ansList = new ArrayList<>();

        if (root == null){
            return ansList;
        }

        //  记录当前遍历到的节点
        TreeNode cur = root;

        while (!stack.isEmpty() || cur != null){
            if (cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            //  左子树为空时,pop 父节点
            //  右子树为空时,左子树已被pop(即跟节点被pop了,pop根节点的根节点),
            else {
                cur = stack.pop();
                ansList.add(cur.val);
                cur = cur.right;
            }
        }
        return ansList;
    }
}
  • 后序
    • 思路
      • 前序 ==> 中左右
      • 中左右 ===>(入栈顺序修改) 中右左 ===>(反转操作) 左中右
public class PostOrder {
    public List<Integer> postorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        List<Integer> ansList = new ArrayList<>();

        if (root == null){
            return ansList;
        }
        //  初始化栈
        stack.push(root);

        TreeNode cur = null;
        //  开始遍历,当栈不为空的时候,就一直遍历下去
        while (!stack.isEmpty()){
            cur = stack.pop();
            if (cur == null) continue;
            else {
                //  当前节点不为空的时候,先将该节点的数据放入 list 中,再将左右子节点入栈
                ansList.add(cur.val);
                if (cur.left != null)   stack.push(cur.left);
                if (cur.right != null) stack.push(cur.right);
            }
        }
        Collections.reverse(ansList);

        return ansList;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值