二叉树先序、中序、后序遍历 递归非递归实现

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class TreeTest {

  /**
   * BFS
   * 先序遍历
   */
  public static void preOrderRecursion(TreeNode root) {
    if (root == null) {
      return;
    }

    System.out.print(root.val + " ");
    if (root.left != null) {
      preOrderRecursion(root.left);
    }
    if (root.right != null) {
      preOrderRecursion(root.right);
    }
  }

  /**
   * DFS
   * 先序遍历
   */
  public static void preOrderNonRecursion(TreeNode root) {
    if (root == null) {
      return;
    }

    Queue<TreeNode> queue = new LinkedList();
    queue.offer(root);

    while (!queue.isEmpty()) {
      TreeNode node = queue.poll();
      System.out.print(node.val + " ");

      if (node.left != null) {
        queue.offer(node.left);
      }

      if (node.right != null) {
        queue.offer(node.right);
      }
    }
  }

  /**
   * DFS
   * 左子树深度优先
   * 中序遍历
   */
  public static void midOrderRecursion(TreeNode root) {
    if (root == null) {
      return;
    }

    if (root.left != null) {
      midOrderRecursion(root.left);
    }
    System.out.print(root.val + " ");
    if (root.right != null) {
      midOrderRecursion(root.right);
    }
  }

  /**
   * DFS
   * 左子树深度优先
   * 中序遍历
   * ********1
   * ****4      5
   * ******8 10  15
   */
  public static void midOrderNonRecursion(TreeNode root) {
    if (root == null) {
      return;
    }

    Stack<TreeNode> stack = new Stack<>();
    TreeNode p = root;

    while (!stack.isEmpty() || p != null) {
      while (p != null) {
        stack.push(p);
        p = p.left;
      }

      if (!stack.isEmpty()) {
        p = stack.pop();
        System.out.print(p.val + " ");

        p = p.right;
      }
    }

  }

  /**
   * 递归的后序遍历
   */
  public static void postOrderRecursion(TreeNode root) {
    if (root == null) {
      return;
    }

    if (root.left != null) {
      postOrderRecursion(root.left);
    }

    if (root.right != null) {
      postOrderRecursion(root.right);
    }

    System.out.print(root.val + " ");
  }

  /**
   * 后序遍历,非递归
   *
   * 先左,再右,最后中
   */
  public static void postOrderNonRecursion(TreeNode root) {
    if (root == null) {
      return;
    }

    TreeNode node = root, prev = root;
    Stack<TreeNode> stack = new Stack();

    while (!stack.isEmpty() || node != null) {
      // 先放跟节点,在放左子树
      while (node != null) {
        stack.push(node);
        node = node.left;
      }

      // 拿出一个节点(根据上一步,没有左子树了),
      // 如果也没有右子树 或者 右子树已经被处理了,则可以出栈,输出了
      TreeNode temp = stack.peek().right;
      if (temp == null || temp == prev) {
        node = stack.pop();
        System.out.print(node.val + " ");

        prev = node;
        node = null;
      // 处理右子树
      } else {
        node = temp;
      }
    }

  }

  public static class TreeNode {

    int val;

    TreeNode left;

    TreeNode right;

    public TreeNode(int x) {
      val = x;
    }
  }

  /**
   * ********1
   * ****4      5
   * ******8 10  15
   */
  public static TreeNode constructTree() {
    TreeNode tn = new TreeNode(1);
    TreeNode tn2 = new TreeNode(4);
    TreeNode tn3 = new TreeNode(5);
    TreeNode tn4 = new TreeNode(8);
    TreeNode tn5 = new TreeNode(10);
    TreeNode tn6 = new TreeNode(15);

    tn.left = tn2;
    tn.right = tn3;

    tn2.right = tn4;

    tn3.left = tn5;
    tn3.right = tn6;
    return tn;
  }

  public static void main(String[] args) {
    TreeNode root = constructTree();
    preOrderRecursion(root);
    System.out.println();
    preOrderNonRecursion(root);
    System.out.println();

    midOrderRecursion(root);
    System.out.println();
    midOrderNonRecursion(root);
    System.out.println();

    postOrderRecursion(root);
    System.out.println();
    postOrderNonRecursion(root);
    System.out.println();
  }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值