数据结构和算法自我学习[0411]

155 阅读1分钟

前言

今天题目

  • 二叉树的遍历
  • 先序遍历
  • 中序遍历
  • 后序遍历
  • 层次遍历

二叉树的遍历


import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

public class Tree0411 {
    public static void main(String[] args) {
   		// 构建先序遍历结果:1-2-3-4-5-6-7的树
        //		   4
        //     2       6
        //   1   3   5   7
        Node node1 = new Node(1, null, null);
        Node node3 = new Node(3, null, null);
        Node node5 = new Node(5, null, null);
        Node node7 = new Node(7, null, null);
        Node node2 = new Node(2, node1, node3);
        Node node6 = new Node(6, node5, node7);
        Node node4 = new Node(4, node2, node6);
        

        //递归先序遍历
        proSort(node4);
        //递归中序遍历
        middleOrder(node4);
        //递归后序遍历
        postOrder(node4);
        //层次遍历
        levelTraverse(node4);

        //非递归先序遍历
        proSortNoRecursion(node4);

        //非递归中序遍历
        inOrderByStack(node4);

        //非递归后序遍历
        postOrderByStack(node4);

    }

    /**
     * 先序递归
     *
     * @param node
     */
    private static void proSort(Node node) {
        //先序排序  根 左 右
        if (node == null) {
            return;
        }
        System.out.print(node.getData());
        proSort(node.getLeft());
        proSort(node.getRight());
    }

    /**
     * 先序不用递归要借助栈来实现
     *
     * @param root
     */
    private static void proSortNoRecursion(Node root) {
        if (root == null) {
            return;
        }
        LinkedList<Node> stack = new LinkedList<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            Node currentNode = stack.poll();
            System.out.print(currentNode.getData() + " ");
            if (currentNode.getRight() != null) {
                //把右节点压入栈
                stack.push(currentNode.getRight());
            }
            if (currentNode.getLeft() != null) {
                stack.push(currentNode.getLeft());
            }
        }
    }

    /**
     * 中序递归
     *
     * @param node
     */
    private static void middleOrder(Node node) {
        if (node == null) {
            return;
        }
        middleOrder(node.getLeft());
        System.out.print(node.getData());
        middleOrder(node.getRight());
    }

    /**
     * 中序非递归
     * 思路:借助栈,总体思路:先把左节点全部压进去,再弹出
     * 具体:左和右节点都是个新的根节点
     *
     * @param root
     */
    private static void inOrderByStack(Node root) {
        if (root == null) {
            return;
        }

        Deque<Node> stack = new LinkedList<>();
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                //把根节点压入栈
                stack.push(root);
                //查看当前根是否存在左节点,存在就压入
                root = root.getLeft();
            }
            //判断是否都弹出了
            if (!stack.isEmpty()) {
                //栈不位空,进行弹出
                root = stack.pop();
                System.out.print(root.getData() + " ");
                //把弹出的节点的右子节点当前新的根。
                root = root.getRight();
            }
        }
    }

    /**
     * 后序递归
     *
     * @param node
     */
    private static void postOrder(Node node) {
        if (node == null) {
            return;
        }
        postOrder(node.getLeft());
        postOrder(node.getRight());
        System.out.println(node.getData());
    }

    /**
     * 后序遍历非递归
     * 后序是前序的改进,前序是压右-左-中,输出是中-左-右。现在改压入为左-右-中,此时输出和后序只是顺序不一样了,
     * 再加多一个栈即可解决。
     */
    private static void postOrderByStack(Node root) {
        if (root == null){
            return;
        }

        LinkedList<Node> stack1 = new LinkedList<>();
        LinkedList<Node> stack2 = new LinkedList<>();
        stack1.push(root);
        while (!stack1.isEmpty()){
            Node current = stack1.poll();
            stack2.push(current);
            if (current.getLeft() != null){
                stack1.push(current.getLeft());
            }
            if (current.getRight() != null){
                stack1.push(current.getRight());
            }
        }

        //把2的吐出来
        while (!stack2.isEmpty()){
            System.out.print(stack2.poll().getData() + " ");
        }
    }

    /**
     * 层级遍历:使用队列+递归实现
     * 注意:是使用当前节点进行获取
     *
     * @param node
     */
    private static void levelTraverse(Node node) {
        if (node == null) {
            return;
        }
        //新建队列,并且把头节点放进来,再对队列进行遍历
        Queue<Node> queue = new LinkedList<>();
        queue.offer(node);
        while (!queue.isEmpty()) {
            //出队并打印数据
            Node currentNode = queue.poll();
            System.out.print(currentNode.getData());
            if (currentNode.getLeft() != null) {
                queue.offer(currentNode.getLeft());
            }
            if (currentNode.getRight() != null) {
                queue.offer(currentNode.getRight());
            }
        }
    }
}

博主:一个大四转行的Java程序员