二叉树的遍历分为两大类:
1、深度优先遍历(前序遍历、中序遍历、后序遍历)
2、广度优先遍历
3
2 8
9 10 null 4
package xiaohui; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; /** * @author 忠哥 * @create 2021-10-24 **/ public class CreateBinaryTreeByLinkedList { /** * 构建二叉树 * * @param linkedList 链表 * @return */ public static TreeNode createTreeNode(LinkedList<Integer> linkedList) { TreeNode node = null; if (linkedList == null || linkedList.isEmpty()) { return null; } //从链表中移除第一个并将其返回 Integer data = linkedList.removeFirst(); //如果元素为空,则不再递归 if (data != null) { node = new TreeNode(data); node.left = createTreeNode(linkedList); node.right = createTreeNode(linkedList); } return node; } /** * 前序遍历 * * @param node */ public static void preOut(TreeNode node) { if (node == null) { return; } System.out.print(node.data + " "); preOut(node.left); preOut(node.right); } /** * 借助栈实现 前序遍历 * * @param root */ public static void preOutStack(TreeNode root) { TreeNode treeNode = root; Stack<TreeNode> stack = new Stack<>(); while (treeNode != null || !stack.isEmpty()) { while (treeNode != null) { System.out.print(treeNode.data + " "); stack.push(treeNode); treeNode = treeNode.left; } if (!stack.isEmpty()) { treeNode = stack.pop(); treeNode = treeNode.right; } } } /** * 用非递归的方式实现二叉树的先序遍历(LeetCode144): * 1、申请一个栈stack,然后将头节点压入stack中。 * 2、从stack中弹出栈顶节点,打印,再将其右孩子节点(不为空的话)先压入stack中,最后将其左孩子节点(不为空的话)压入stack中。 * 3、不断重复步骤2,直到stack为空,全部过程结束。 * * @param root */ private static void doPreOutStack(TreeNode root) { Stack<TreeNode> stack = new Stack<>(); if (root != null) { stack.push(root); while (!stack.empty()) { TreeNode node = stack.pop(); System.out.print(node.data + " "); if (node.right != null) { stack.push(node.right); } if (node.left != null) { stack.push(node.left); } } } } /** * 中序遍历 * * @param node */ public static void midOut(TreeNode node) { if (node == null) { return; } midOut(node.left); System.out.print(node.data + " "); midOut(node.right); } /** * 用非递归的方式实现二叉树的中序遍历(LeetCode94): * 1、申请一个栈stack,初始时令cur=head * 2、先把cur压入栈中,依次把左边界压入栈中,即不停的令cur=cur.left,重复步骤2 * 3、不断重复2,直到为null,从stack中弹出一个节点,记为node,打印node的值,并令cur=node.right,重复步骤2 * 4、当stack为空且cur为空时,整个过程停止。 * * @param root */ private static void doMidOutStack(TreeNode root) { Stack<TreeNode> stack = new Stack<>(); if (root != null) { while (root != null || !stack.isEmpty()) { if (root != null) { stack.push(root); root = root.left; } else { root = stack.pop(); System.out.print(root.data + " "); root = root.right; } } } } /** * 后序遍历 * * @param node */ public static void lastOut(TreeNode node) { if (node == null) { return; } lastOut(node.left); lastOut(node.right); System.out.print(node.data + " "); } /** * 用非递归的方式实现二叉树的后序遍历(LeetCode145): * 用非递归的方式实现后序遍历有点麻烦。 * 1、申请一个栈s1,然后将头节点压入栈s1中。 * 2、从s1中弹出的节点记为cur,然后依次将cur的左孩子节点和右孩子节点压入s1中。 * 3、在整个过程中,每一个从s1中弹出的节点都放进s2中。 * 4、不断重复步骤2和步骤3,直到s1为空,过程停止。 * 5、从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序。 * * @param root */ private static void doLastOutStack(TreeNode root) { Stack<TreeNode> stack1 = new Stack<>(); Stack<TreeNode> stack2 = new Stack<>(); if (root != null) { stack1.push(root); while (!stack1.isEmpty()) { root = stack1.pop(); stack2.push(root); if (root.left != null) { stack1.push(root.left); } if (root.right != null) { stack1.push(root.right); } } while (!stack2.isEmpty()) { System.out.print(stack2.pop().data + " "); } } } /** * 二叉树广度优先遍历(层序遍历) * * @param root */ private static void levelOrderTraversal(TreeNode root) { Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { TreeNode node = queue.poll(); System.out.print(node.data + " "); if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } } public static void main(String[] args) { LinkedList linkedList = new LinkedList<Integer>(Arrays.asList(new Integer[]{3, 2, 9, null, null, 10, null, null, 8, null, 4})); TreeNode node = createTreeNode(linkedList); System.out.println("前序遍历..."); preOut(node); System.out.println(); System.out.println("借助栈实现前序遍历01..."); preOutStack(node); System.out.println(); System.out.println("借助栈实现前序遍历02..."); doPreOutStack(node); System.out.println(); System.out.println("中序遍历..."); midOut(node); System.out.println(); System.out.println("中序遍历Stack..."); doMidOutStack(node); System.out.println(); System.out.println("后序遍历..."); lastOut(node); System.out.println(); System.out.println("后序遍历Stack..."); doLastOutStack(node); System.out.println(); System.out.println("广度优先遍历..."); levelOrderTraversal(node); } }
执行结果如下:
前序遍历...
3 2 9 10 8 4
借助栈实现前序遍历01...
3 2 9 10 8 4
借助栈实现前序遍历02...
3 2 9 10 8 4
中序遍历...
9 2 10 3 8 4
中序遍历Stack...
9 2 10 3 8 4
后序遍历...
9 10 2 4 8 3
后序遍历Stack...
9 10 2 4 8 3
广度优先遍历...
3 2 8 9 10 4