java 二叉树的前、中、后序遍历

  1. 二叉树是递归定义的,每个节点在其子树上都是根节点,都有左右子树
    在这里插入图片描述
    在这里插入图片描述
  2. 访问节点操作发生在第一次经过节点时左右,就是前序遍历
  3. 访问节点操作发生在第二次经过节点时,左右,就是中序遍历
  4. 访问节点操作发生在第三次经过节点时,左右,就是后序遍历
  5. 所谓的遍历,就是对树中的每个节点仅仅做一次访问操作,对根节点访问顺序,形成了遍历顺序
  6. 先序:1 2 4 8 9 5 3 6 7
    中序:8 4 9 2 5 1 6 3 7
    后序:8 9 4 5 2 6 7 3 1
  7. 递归遍历 java 代码
public class Test {
  public static void main(String[] args) {
    TreeNode root = createTree();
    preOrderRe(root);
    System.out.println();

    inOrderRe(root);
    System.out.println();

    postOrderRe(root);
    System.out.println();
  }

  public static TreeNode createTree() {
    TreeNode[] nodes = new TreeNode[10]; // 生成一颗完全二叉树
    int i, l, r;
    for (i = 1; i < 10; i++) { // 从 1 开始
      nodes[i] = new TreeNode(i);
    }
    for (i = 1; i <= 9; i++) {
      l = 2*i;
      r = 2*i + 1;
      if (l < 10) {
        nodes[i].left = nodes[l];
      }
      if (r < 10) {
        nodes[i].right = nodes[r];
      }
    }
    return nodes[1];
  }

  public static void preOrderRe(TreeNode root) {
    if (root == null) {
      return;
    }
    root.show(); // 先序遍历根节点
    preOrderRe(root.left);
    preOrderRe(root.right);
  }

  public static void inOrderRe(TreeNode root) {
    if (root == null) {
      return;
    }
    inOrderRe(root.left);
    root.show(); // 中序遍历根节点
    inOrderRe(root.right);
  }

  public static void postOrderRe(TreeNode root) {
    if (root == null) {
      return;
    }
    postOrderRe(root.left);
    postOrderRe(root.right);
    root.show(); // 后序遍历根节点
  }

}

// 二叉树节点类型
class TreeNode {
  int value;
  TreeNode left;
  TreeNode right;
  TreeNode(int value) {
    this.value = value;
  }

  public void show() {
    System.out.print(value + " ");
  }
}
  1. 非递归遍历 java 代码
// 非递归用栈来保存之前走过的路径,当访问完子树后,可以返回到父节点,继续访问
public static void preOrder(TreeNode root) {
	Stack<TreeNode> stack = new Stack<>();
	TreeNode cur = root;
    while (!stack.isEmpty() || cur != null) {
        if (cur != null) {
        	 cur.show();
            stack.push(cur);
            cur = cur.left;
        } else {
            cur = stack.pop();
            cur = cur.right;
        }
    }
  }
  
public static void inOrder(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (!stack.isEmpty() || cur != null) {
        if (cur != null) {
            stack.push(cur);
            cur = cur.left;
        } else {
            cur = stack.pop();
            cur.show();
            cur = cur.right;
        }
    }
  }
  
// 后序遍历需要判断是从左子树返回还是右子树返回,只有当右子树返回时,才访问父节点,而当从左子树返回时,应该访问右子树
public static void postOrder(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root, pre = null;  
    while (cur != null || !stack.isEmpty()) {
    	if (cur != null) {
        stack.push(cur);
        cur = cur.left;
      } else {
        cur = stack.peek(); // 到最左边的节点,取出该节点
        // 如果不存在右节点或者右节点已经访问了
        if (cur.right == null || cur.right == pre) {
          stack().pop().show(); // 出栈并访问节点
          pre = cur; // pre 表示已访问的节点
          cur = null; // cur 表示下一个将要访问的节点,此处表示回退到父节点
        } else {
          cur = cur.right; // 右节点没有访问,转到右节点
        }
      }
    }
  }

// 层次遍历用队列实现
public static void levelOrder(TreeNode root) {
    if (root == null) {
      return;
    }
    LinkedList<TreeNode> queue = new LinkedList<>();
    queue.add(root); // 根节点先入队,不同于前面三个
    while (!queue.isEmpty()) {
      root = queue.poll();
      root.show();
      if (root.left != null) {
        queue.add(root.left);
      }
      if (root.right != null) {
        queue.add(root.right);
      }
    }
  }

参考1
参考2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值