千军万马一将在,探囊取物有何难,看我如何轻松斩落二叉树的遍历!!

332 阅读1分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

二叉树的遍历

递归的前中后序遍历

前序遍历

访问根节点——>根的左子树——>根的右子树 在这里插入图片描述 打印:A B D E H C F G

public void preOrderTraversal(Node root){
        if(root == null){
            return;
        }
        System.out.println(root);
        preOrderTraversal(root.left);
        preOrderTraversal(root.right);
}

在这里插入图片描述

返回list的前序遍历

    public List<String> preOrderTraversal(Node root){
        List<String> list = new LinkedList<>();
        if(root == null){
        //此处不能是null,因为addAllc的参数不能为null
            return list;
        }
        list.add(root.getVal());
        list.addAll(preOrderTraversal(root.left));
        list.addAll(preOrderTraversal(root.right));
        return list;
    }

中序遍历

根的左子树——>访问根节点——>根的右子树 在这里插入图片描述 打印:D B E H A F C G

    public void inpOrderTraversal(Node root){
        if(root == null){
            return;
        }
        preOrderTraversal(root.left);
        System.out.print(root);
        preOrderTraversal(root.right);
    }

返回list的中序遍历

    public List<String> inOrderTraversal(Node root){
        List<String> list = new LinkedList<>();
        if(root == null){
        //此处不能是null,因为addAllc的参数不能为null
            return list;
        }
        list.addAll(preOrderTraversal(root.left));
        list.add(root.getVal());
        list.addAll(preOrderTraversal(root.right));
        return list;
    }

后序遍历

根的左子树——>根的右子树——>访问根节点 在这里插入图片描述 打印:D H E B F G C A

    public void postOrderTraversal(Node root){
        if(root == null){
            return;
        }
        preOrderTraversal(root.left);
        preOrderTraversal(root.right);
        System.out.print(root);
    }

返回list的后序遍历

    public List<String> postOrderTraversal(Node root){
        List<String> list = new LinkedList<>();
        if(root == null){
        //此处不能是null,因为addAllc的参数不能为null
            return list;
        }
        list.addAll(preOrderTraversal(root.left));
        list.addAll(preOrderTraversal(root.right));
        list.add(root.getVal());
        return list;
    }

非递归的前中后序遍历

前序遍历

递归转为非递归,用栈可以模拟递归的路线 cur指向根节点,来遍历整个树 如果cur不为null,将cur放入栈中,然后继续向左走,放入栈中的根节点用于在后面寻找其右树 当cur为空时,出栈顶元素(根节点)找到其右树,让cur 继续遍历其右树

    public void preOrderTraversalNor(Node root) {
        if (root == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        Node cur = root;
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                System.out.print(cur);
                cur = cur.left;
            }
            Node top = stack.pop();
            cur = top.right;
        }
    }

中序遍历

    public void inOrderTraversalNor(Node root) {
        if (root == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        Node cur = root;
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            Node top = stack.pop();
            System.out.print(top);
            cur = top.right;
        }
    }

后序遍历(有点难哦)

  1. 同样的用cur指向根节点,遍历整个树

  2. 如果cur不为空,将cur放入栈中,然后cur继续遍历左树

  3. 当cur为空时,获取栈顶元素(仅获取,并不提出,因为此时并不能打印这个元素),cur指向栈顶元素

  4. 判断cur的右树是否为空,如果为空,提出栈顶元素(可以打印了),并将cur置空,继续第3步循环,同时,如果cur的右树被打印过,同样执行这个操作 在这里插入图片描述

  5. 如果cur右树不为空,让cur指向其右树的根节点,遍历右树,继续第2步的循环

    public void postOrderTraversalNor(Node root){
        if(root == null){
            return;
        }
        Stack<Node> stack = new Stack<>();
        Node cur = root;
        Node pre = null;  //用来指定上一次被打印的元素
        while(cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.peek(); //必须是peek,不能是pop,不能过早的把D提出来,否则最后无法打印D了
            if(cur.right == null || cur.right == pre){
                Node popNode = stack.pop();
                System.out.print(popNode);
                pre = popNode;
                cur = null;
            }else{
                cur = cur.right;
            }
        }
    }

层序遍历

在这里插入图片描述 需要使用队列

  1. 判断A是否为空,如果为空,直接返回;如果不为空,将其放入到队列中
  2. 出队列的头元素并打印,这个根节点的左树不为空放左树根节点,右树不为空放右树根节点
  3. 继续循环 在这里插入图片描述
    public void levelOrderTraversal(Node root){
        if(root == null){
            return;
        }
        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            Node top = queue.poll();
            System.out.print(top);
            if(top.left != null){
                queue.offer(top.left);
            }
            if(top.right != null){
                queue.offer(top.right);
            }
        }
    }

请添加图片描述

看威震天如何在洛杉矶湖人掀起狂风巨浪!!!!