二叉树遍历分为三种:前序、中序、后序,其中序遍历最为重要。为啥叫这个名字?是根据根节点的顺序命名的。
比如上图正常的一个满节点,A:根节点、B:左节点、C:右节点,前序顺序是ABC(根节点排最先,然后同级先左后右);中序顺序是BAC(先左后根最后右);后序顺序是BCA(先左后右最后根)。
比如上图二叉树遍历结果
前序遍历:ABCDEFGHK
中序遍历:BDCAEHGKF
后序遍历:DCBHKGFEA
分析中序遍历如下图,中序比较重要(java很多树排序是基于中序,后面讲解分析)
public class BinaryTree { int data; BinaryTree left; BinaryTree right; @Override public String toString() { return "BinaryTree{" + "data=" + data + '}'; } public BinaryTree(int data) { this.data = data; left = null; right = null; } public BinaryTree(){} //插入数据 public void insert(BinaryTree root, int data) { //判断数据是否比当前节点值大 if (data > root.data) { //如果右节点为null先创建对象,并赋值 if (root.right == null) { root.right = new BinaryTree(data); } else { //否则递归 this.insert(root.right, data); } } else {//判断数据是否比当前节点值小 if (root.left == null) { root.left = new BinaryTree(data); } else { this.insert(root.left, data); } } } public static void preOrder(BinaryTree root) { if (root != null) { //输出当前节点 System.out.print(root.data + "-"); //以递归的方式遍历出所有子孙左节点 preOrder(root.left); //以递归的方式遍历出所有子孙左节点 preOrder(root.right); } } public static void inOrder(BinaryTree root) { if (root != null) { //先以递归的方式递归到最小的最节点,然后依次返回 inOrder(root.left); //从小到大输出当前节点 System.out.print(root.data + "-"); //以递归的方式遍历出所有子孙左节点 inOrder(root.right); } } public static void postOrder(BinaryTree root) { if (root != null) { postOrder(root.left); postOrder(root.right); System.out.print(root.data + "-"); } } public static void preOrderNoRecursion(BinaryTree root) { System.out.println("非递归先序遍历:"); LinkedList<BinaryTree> stack = new LinkedList<BinaryTree>(); stack.push(root); BinaryTree current = null; while (!stack.isEmpty()) { current = stack.pop(); System.out.print(current.data + "_"); if (current.right != null) { stack.push(current.right); } if (current.left != null) { stack.push(current.left); } } } public static void inOrderNoRecursion(BinaryTree root) { System.out.println("非递归中序遍历:"); LinkedList<BinaryTree> stack = new LinkedList<BinaryTree>(); BinaryTree current = root; while (current != null || !stack.isEmpty()) { while (current != null) { stack.push(current); current = current.left; } if (!stack.isEmpty()) { current = stack.pop(); System.out.print(current.data + "_"); current = current.right; } } } public static void postOrderNoRecursion(BinaryTree root) { System.out.println("非递归后序遍历:"); LinkedList<BinaryTree> stack = new LinkedList<BinaryTree>(); BinaryTree current = root; BinaryTree rNode = null; while (current != null || !stack.isEmpty()) { //判断左节点是否为空 while (current != null) { //存放左节点(当前节点) stack.push(current); current = current.left; } //取出放入的最后一个节点为当前节点 current = stack.pop(); //判断当前节点是否为空,并且当前节点右节点为null while (current != null && (current.right == null || current.right == rNode)) { //输出当前节点值 System.out.print(current.data + "-"); rNode = current; if (stack.isEmpty()) return; //再取出一个节点为当前节点 current = stack.pop(); } stack.push(current); current = current.right; } } public static void main(String[] args) { int[] array = { 55, 76, 35, 22, 16, 48, 90, 46,75, 9, 40 }; BinaryTree root = new BinaryTree(array[0]); for (int i = 1; i < array.length; i++) { root.insert(root, array[i]); // 向二叉树中插入数据 } // System.out.println("先根遍历:"); // preOrder(root); inOrderNoRecursion(root); // System.out.println(); // System.out.println("中根遍历:"); // inOrder(root); // System.out.println(); // System.out.println("后根遍历:"); // postOrder(root); postOrderNoRecursion(root); } }