二叉树的递归和非递归遍历的Java实现

二叉树的遍历

1 前序遍历

二叉树的前序遍历顺序为:根->左->右

递归代码如下:

/**
 * 二叉树前序遍历递归
 * @param root
*/
public void preorderTraverse(TreeNode root) {
    if (root == null)
      return;
    System.out.println(root.val);
    // 遍历左子树
    preorderTraverse(root.left);
    // 遍历右子树
    preorderTraverse(root.right);
}

非递归算法利用了栈来实现。

/**
 * 二叉树前序遍历非递归
 * @param root
*/
public void preorderTraverseWithStack(TreeNode root) {
    if (root == null)
      return;
    TreeNode cur = root;
    Stack<TreeNode> stack = new Stack<>();

    while (cur != null || !stack.isEmpty()) {
      while (cur != null) {
        stack.push(cur);
        System.out.println(cur.val);
        cur = cur.left;
      }
      TreeNode node = stack.pop();
      cur = node.right;
    }
}

前序遍历是是一直遍历左子树,遍历一个结点就输出一个结点,然后再将结点入栈。遍历到最左边结点后,开始出栈。输出栈顶元素。并且需要判断栈顶元素是否有右子树,如果有,继续先序遍历右子树

2 中序遍历

二叉树的前序遍历顺序为:左->根->右

递归代码如下:

/**
 * 二叉树中序遍历递归
 * @param root
*/
public void inorderTraverse(TreeNode root) {
    if (root == null)
      return;
    inorderTraverse(root.left);
    System.out.println(root.val);
    inorderTraverse(root.right);
}

非递归代码如下:

/**
 * 二叉树中序遍历非递归
 * @param root
*/
public void inorderTraverseWithStack(TreeNode root) {
    if (root == null)
      return;
    TreeNode cur = root;
    Stack<TreeNode> stack = new Stack<>();
    while (cur != null || !stack.isEmpty()) {
      while (cur != null) {
        stack.push(cur);
        cur = cur.left;
      }
      TreeNode pop = stack.pop();
      System.out.println(pop.val);
      cur = cur.right;
    }
}

这里需要对比前序遍历的代码。中序遍历是一直沿着左子树深入,然后没遍历一个结点,就将该结点入栈,先不打印。等遍历到最左边结点后,开始出栈,并打印栈顶元素。然后判断栈顶元素是否有右子树,如果有,则继续遍历右子树。

3 后序遍历

二叉树的前序遍历顺序为:左->右->根

递归代码如下:

/**
 * 二叉树后序遍历递归
 * @param root
*/
public void poseOrderTraverse(TreeNode root) {
    if (root == null)
      return;
    poseOrderTraverse(root.left);
    poseOrderTraverse(root.right);
    System.out.println(root.val);
}

非递归代码如下:

/**
 * 二叉树后序遍历非递归
 * @param root
*/
public void postOrderWithStack(TreeNode root) {
    if (root == null)
      return;
    TreeNode cur = root;
    TreeNode pre = null;
    Stack<TreeNode> stack = new Stack<>();
    while (cur != null || !stack.isEmpty()) {
      while (cur != null) {
        stack.push(cur);
        cur = cur.left;
      }
      // 因为左子树已经遍历到不存在左子树到结点了,因此这里是需要判断栈顶元素是否有右子树
      // 如果存在右子树,那么先去继续后续遍历右子树 否则直接栈顶元素出栈
      cur = stack.peek();
      if (cur.right != null || pre == cur.right) {
        // 说明栈顶元素不存在右子树或者右子树已经遍历完毕
        // 那么可以出栈了
        TreeNode pop = stack.pop();
        System.out.println(pop.val);
        pre = pop;
        cur = null;
      } else {
        // 不满足条件则说明栈顶元素还有右子树,并且右子树没有被遍历,那么先对右子树进行后续遍历
        cur = cur.right;
      }
    }
}

后序遍历也是先沿着左子树深入,每遍历一个结点就入栈。遍历到最左边结点后,开始出栈。出栈之前需要判断栈顶元素是否有右子树或者右子树是否已经遍历完了。如果满足上述条件,则出栈。否则继续遍历右子树。

4 层序遍历

层序遍历就是按照二叉树每一层,从左到右进行遍历。

层序遍历一般采用的都是基于队列的非递归算法。代码如下:

/**
 * 二叉树层序遍历
 * @param root
*/
public void levelTraverse(TreeNode root) {
    if (root == null)
      return;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
      TreeNode poll = queue.poll();
      System.out.println(poll.val);
      if(poll.left != null)
        queue.offer(poll.left);
      if (poll.right != null)
        queue.offer(poll.right);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值