关于二叉树的前序、中序、后序三种遍历(递归与非递归)

二叉树遍历分为三种:前序、中序、后序,其中序遍历最为重要。为啥叫这个名字?是根据根节点的顺序命名的。

比如上图正常的一个满节点,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);
        }

}

猜你喜欢

转载自www.cnblogs.com/leduo-zuul/p/10693272.html