java数据结构与算法之二叉树遍历

Posted wen-pan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java数据结构与算法之二叉树遍历相关的知识,希望对你有一定的参考价值。

一、递归实现二叉树前中后遍历

递归实现二叉树遍历代码非常简单,主要是掌握好递归序,写好递归出口就可以了。

1、递归实现二叉树先序遍历
public static void preorderTraversal(final TreeNode head) {
    // basecase
    if (head == null) {
        return;
    }
    System.out.print(head.data + ",");
    preorderTraversal(head.left);
    preorderTraversal(head.right);
}
2、递归实现二叉树中序遍历
public static void inorderTraversal(final TreeNode head) {
    // basecase
    if (head == null) {
        return;
    }
    inorderTraversal(head.left);
    System.out.print(head.data + ",");
    inorderTraversal(head.right);
}
3、递归实现二叉树后序遍历
public static void postorderTraversal(final TreeNode head) {
    // basecase
    if (head == null) {
        return;
    }
    postorderTraversal(head.left);
    postorderTraversal(head.right);
    System.out.print(head.data + ",");
}

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

能用递归实现的就一定能用非递归实现。

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

主要流程:

  1. 先将头节点压入栈中
  2. 从栈中弹出一个节点,弹出该节点就打印该节点的值
  3. 如果这个节点有左右节点,然后将这个节点的左右节点压栈(先压右再压左
  4. 重复上面三步,直到栈stack为空
public static void preorderTraversalNoProcess(final TreeNode head) {
    final Stack<TreeNode> stack = new Stack<>();
    stack.push(head);

    while (!stack.isEmpty()) {
        final TreeNode pop = stack.pop();
        // 弹出就打印
        System.out.print(pop.data);
        // 先压右再压左
        if (pop.right != null) {
            stack.push(pop.right);
        }
        if (pop.left != null) {
            stack.push(pop.left);
        }
    }
}
2、非递归实现二叉树中序遍历

主要流程:

核心思想:任何一颗二叉树都能被左边界分解掉。

具体步骤:

  1. 从一棵树的头节点开始,将整棵树的左边界压入到栈里
  2. 压入完左边界后,从栈中弹出一个节点,打印该节点的值
  3. 然后对这个弹出节点的左节点又进行第一步的操作
public static void inorderTraversalNoProcess(final TreeNode head) {
  final Stack<TreeNode> stack = new Stack<>();
  TreeNode current = head;

  while (!stack.isEmpty() || current != null) {
    // 把左边界依次压栈
    if (current != null) {
      stack.push(current);
      current = current.left;
    } else {
      // 如果没有左节点了,则从栈中弹一个元素出来,对这个弹出来的元素的右边界也依次压栈
      final TreeNode node = stack.pop();
      // 弹出就打印
      System.out.print(node.data);
      current = node.right;
    }
  }
}
3、非递归实现二叉树后序遍历

主要流程:

和先序遍历过程比较类似!这里需要用到两个栈空间。只是这里不是弹出就打印了,而是弹出后放入到另一个栈中。

具体步骤:

  1. 准备两个栈 stack1 和stack2,先将头节点压入到stack1中
  2. 弹出stack1中的节点,这里弹出该节点后直接push到stack2中 (先序遍历是弹出就打印)
  3. 如果该节点有左右节点,则将该节点的左右节点压入到stack1中(先压左再压右
  4. 重复以上三步,直到栈stack1为空
public static void postorderTraversalNoProcess(final TreeNode head) {
  if (head == null) {
        return;
    }
    final Stack<TreeNode> stack1 = new Stack<>();
    final Stack<TreeNode> stack2 = new Stack<>();
    // 先将头节点压入栈中
    stack1.push(head);
    while (!stack1.isEmpty()) {
        // 从栈中弹出一个节点,弹出后把该节点压入到stack2中
        final TreeNode node = stack1.pop();
        stack2.push(node);
        // 先压左再压右
        if (head.left != null) {
            stack1.push(head.left);
        }
        if (head.right != null) {
            stack1.push(head.right);
        }
    }
    // 最后将stack2中的节点倒出来即可(完成了后续遍历)
    while (!stack2.isEmpty()) {
        final TreeNode node = stack2.pop();
        System.out.println(node.data + " , ");
    }
}

以上是关于java数据结构与算法之二叉树遍历的主要内容,如果未能解决你的问题,请参考以下文章

java数据结构与算法之二叉树深度优先和广度优先遍历

java数据结构与算法之二叉树的最大宽度和最大深度问题

java数据结构与算法之二叉树的最大宽度和最大深度问题

java数据结构之二叉树遍历的非递归实现

数据结构与算法之二叉树 ——in dart

数据结构与算法(Java)之二叉树