java实现二叉树遍历
java二叉树遍历,最复杂的是非递归的后序遍历
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.LinkedList; public class BinaryTree<T> { private BinaryNode<T> root; public BinaryTree(BinaryNode<T> root) { this.root = root; } public BinaryTree() { this.root = null; } public boolean isEmpty() { return this.root == null; } public BinaryNode<T> leftChild() { return this.root.left; } public BinaryNode<T> rightChild() { return this.root.right; } public void setRoot(BinaryNode<T> root) { this.root = root; } public void setLeft(BinaryNode<T> left) { this.root.left = left; } public void setRight(BinaryNode<T> right) { this.root.right = right; } @Data @AllArgsConstructor @NoArgsConstructor static class BinaryNode<T> { private T data; private BinaryNode<T> left; private BinaryNode<T> right; } /** * 宽度优先遍历 */ public void levelOrder(BinaryNode<T> root) { java.util.Queue<BinaryNode<T>> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { BinaryNode<T> node = queue.remove(); if (node == null) { continue; } System.out.println(node.data); queue.add(node.left); queue.add(node.right); } } /** * 先根遍历-递归实现 * * @param t */ public void preOrder(BinaryNode<T> t) { //递归结束条件 if (t == null) { return; } else { System.out.println(t.data); } preOrder(t.left); preOrder(t.right); } /** * 中根遍历-递归实现 * * @param t */ public void midOrder(BinaryNode<T> t) { if (t == null) { return; } midOrder(t.left); System.out.println(t.data); midOrder(t.right); } /** * 后根遍历-递归实现 * * @param t */ public void postOrder(BinaryNode<T> t) { if (t == null) { return; } postOrder(t.left); postOrder(t.right); System.out.println(t.data); } /** * 先根遍历-非递归实现 * 先根,然后根的左子树,一直向下左子树,此时右子树尚未访问,所有需要先暂存一下 * 左到头了,此时需要访问最底层的右子树,只需要从栈中取出最后进栈的右子树 * 拿到右子树之后,又是先根,然后左到底 * 所以需要使用栈这种后进先出的数据结构 * * @param t */ public void preOrderNoRec(BinaryNode<T> t) { java.util.Stack<BinaryNode<T>> stack = new java.util.Stack<>(); while (t != null || !stack.isEmpty()) { while (t != null) { System.out.println(t.data); stack.push(t.right); t = t.left; } t = stack.pop(); } } /** * 中根遍历-非递归实现 * 1。先左子树,一直到底,然后根节点,然后根的右子树 * 2。根的右子树又是新的一轮循环,还是跟1一样的顺序 * * @param t */ public void midOrderNoRec(BinaryNode<T> t) { java.util.Stack<BinaryNode<T>> stack = new java.util.Stack<>(); while (t != null || !stack.isEmpty()) { //递归向左 while (t.left != null) { stack.push(t); t = t.left; } //如果有左,就左到头,打印最下的左节点 //如果没有左节点,那么跳过上面的while循环,打印根节点 System.out.println(t.data); //判断是否还有未遍历的根节点,取出然后打印当前根 if (!stack.isEmpty()) { t = stack.pop(); System.out.println(t.data); } //切到右子树 t = t.right; } } /** * 后根遍历-非递归实现 * 最复杂 * @param t */ public void postOrderNoRec(BinaryNode<T> t) { java.util.Stack<BinaryNode<T>> stack = new java.util.Stack<>(); while (t != null || !stack.isEmpty()) { //t节点入栈 while (t != null) { stack.push(t); //如果左节点不为空,则递归向左,否则递归向右 if (t.left != null) { t = t.left; } else { t = t.right; } } //直到t到达既没有左也没有右,取出t打印 t = stack.pop(); System.out.println(t.data); //栈不空,且当前节点是栈顶的左子节点,切换到右子树 //如果父节点尚未访问,且当前是父节点的左孩子,递归访问父节点的右孩子 //否则说明本节点是右孩子,结束本轮循环,从栈顶再重新取一个节点开始 if (!stack.isEmpty() && stack.peek().left == t) { t = stack.peek().right; } else { t = null; } } } public static void main(String[] args) { BinaryTree<Integer> tree = new BinaryTree<>(); BinaryNode<Integer> root = new BinaryNode<>(1, null, null); BinaryNode<Integer> leftL = new BinaryNode<>(4, null, null); BinaryNode<Integer> leftR = new BinaryNode<>(5, null, null); BinaryNode<Integer> left = new BinaryNode<>(2, leftL, leftR); BinaryNode<Integer> rightL = new BinaryNode<>(6, null, null); BinaryNode<Integer> rightR = new BinaryNode<>(7, null, null); BinaryNode<Integer> right = new BinaryNode<>(3, rightL, rightR); tree.setRoot(root); tree.setLeft(left); tree.setRight(right); System.out.println("=======levelOrder========="); tree.levelOrder(tree.root); // System.out.println("=======preOrder========="); // tree.preOrder(tree.root); // System.out.println("=======midOrder========="); // tree.midOrder(tree.root); System.out.println("=======postOrder========="); tree.postOrder(tree.root); // System.out.println("=======preOrderNoRec========="); // tree.preOrderNoRec(tree.root); // System.out.println("=========midOrderNoRec==============="); // tree.midOrderNoRec(tree.root); System.out.println("=========================="); tree.postOrderNoRec(tree.root); } }