美文网首页
32:从上到下打印二叉树

32:从上到下打印二叉树

作者: stoneyang94 | 来源:发表于2018-07-19 22:01 被阅读0次

习惯github pages风格的请看我的另一篇博客

题目32:从上到下打印二叉树

  1. 不分行从上到下打印二叉树
  2. 分行从上到下打印二叉树
  3. 之字形打印二叉树

题目 1. 不分行从上到下打印二叉树

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

二叉树结点

    public static class BinaryTreeNode {
        int value;
        BinaryTreeNode left;
        BinaryTreeNode right;
        public BinaryTreeNode(){
        }
        public BinaryTreeNode(int value){
            this.value = value;
        }
    }

举例说明

如下的二叉树

            8
         /     \
        6       10
       /  \      / \
      5   7     9  11

则依次打印出8 6 10 5 7 9 11

解题思路

考查树的遍历算法。
从上到下打印二叉树的规律:

  1. 每一次打印一个结点的时候,如果该结点有子结点, 则把该结点的子结点放到一个队列的末尾
  2. 接下来到队列的头部取出最早进入队列的结点
  3. 重复前面的打印操作,直至队列中所有的结点都被打印出来为止

代码实现:

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

public class _3200{
    public static class BinaryTreeNode {
        int value;
        BinaryTreeNode left;
        BinaryTreeNode right;
        public BinaryTreeNode(){
        }
        public BinaryTreeNode(int value){
            this.value = value;
        }
    }

    public static void printFromTopToBottom(BinaryTreeNode root) {
        if (root != null) { // 当结点非空时才进行操作
            // 用于存放还未遍历的元素
            Queue<BinaryTreeNode> list = new LinkedList<>();
            list.add(root);            //   根结点入队
            BinaryTreeNode cur;  //   当前处理的结点
            while (!list.isEmpty() ) { 
                cur = list.remove(); // 删除队首
                System.out.print(cur.value + " ");  //  输出队首元素的值
                // 如果左子结点不为空,则左子结点入队
                if (cur.left != null) {
                    list.add(cur.left);
                }
                // 如果右子结点不为空,则左子结点入队
                if (cur.right != null) {
                    list.add(cur.right);
                }
            }
        }
    }

    public static void main(String[] args) {
        //       8
        //    /    \
        //   6     10
        //  / \   / \
        // 5   7 9  11
        BinaryTreeNode n1 = new BinaryTreeNode(8);
        BinaryTreeNode n2 = new BinaryTreeNode(6);
        BinaryTreeNode n3 = new BinaryTreeNode(10);
        BinaryTreeNode n4 = new BinaryTreeNode(5);
        BinaryTreeNode n5 = new BinaryTreeNode(7);
        BinaryTreeNode n6 = new BinaryTreeNode(9);
        BinaryTreeNode n7 = new BinaryTreeNode(11);
        n1.left = n2;
        n1.right = n3;
        n2.left = n4;
        n2.right = n5;
        n3.left = n6;
        n3.right = n7;
        printFromTopToBottom(n1);
    }
}
不分行从上到下打印二叉树

扩展:

  • 从上到下按层遍历二叉树,从本质上来说就是广度优先遍历二叉树
  • 不管是广度优先遍历一幅有向图还是一棵树,都要用到队列
  • 首先把起始节点(树中为根结点)放入队列,接下来每次从队列的头部取出一个节点,遍历这个节点后把它能到达的节点(树中为子结点)都依次放入队列。重复这个遍历过程,直到队列中的节点全部都遍历为止

题目 2. 分行从上到下打印二叉树

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

举例说明

如下的二叉树

            8
         /     \
        6       10
       /  \      / \
      5   7     9  11

则依次打印出

8  
6 10 
5 7 9 11

解题思路

队列来保存要打印的节点。
同时我们需要两个变量:一个变量表示在当前层中还没有打印的节点数;另一个变量表示下一层节点的数目

代码实现

import java.util.LinkedList;
import java.util.List;

public class _3201{
    public static class BinaryTreeNode {
        int value;
        BinaryTreeNode left;
        BinaryTreeNode right;
        public BinaryTreeNode(){
        }
        public BinaryTreeNode(int value){
            this.value = value;
        }
    }

    public static void print(BinaryTreeNode root) {
        if (root == null) {
            return;
        }
        List<BinaryTreeNode> list = new LinkedList<>();
        BinaryTreeNode node;
        int current = 1;// 当前层的结点个数,开始时只有根节点一个
        int next = 0;// 下一层的结点个数
        list.add(root);
        while (list.size() > 0) {
            node = list.remove(0);
            current--;
            System.out.print(" "+node.value);
            if (node.left != null) {
                list.add(node.left);
                next++;
            }
            if (node.right != null) {
                list.add(node.right);
                next++;
            }
            if (current ==0) {
                System.out.println();//本层打印完了
                current = next;//现在处理下一层
                next = 0;
            }
        }
    }

    public static void main(String[] args) {
        //       8
        //    /    \
        //   6     10
        //  / \   / \
        // 5   7 9  11
        BinaryTreeNode n1 = new BinaryTreeNode(8);
        BinaryTreeNode n2 = new BinaryTreeNode(6);
        BinaryTreeNode n3 = new BinaryTreeNode(10);
        BinaryTreeNode n4 = new BinaryTreeNode(5);
        BinaryTreeNode n5 = new BinaryTreeNode(7);
        BinaryTreeNode n6 = new BinaryTreeNode(9);
        BinaryTreeNode n7 = new BinaryTreeNode(11);
        n1.left = n2;
        n1.right = n3;
        n2.left = n4;
        n2.right = n5;
        n3.left = n6;
        n3.right = n7;
        print(n1);
    }
}
分行从上到下打印二叉树

题目 3. 之字形打印二叉树

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。(每一层打印到一行。)

举例说明

如下的二叉树

            8
         /     \
        6       10
       /  \      / \
      5   7     9  11

则依次打印出

8  
10 6 
5 7 9 11

解题思路

按之字形顺序打印二叉树需要两个栈。

  • 我们在打印某一行结点时,把下一层的子结点保存到相应的栈里
  • 如果当前打印的是奇数层,则先保存左子结点再保存右子结点到一个栈里
  • 如果当前打印的是偶数层,则先保存右子结点再保存左子结点到第二个栈里

代码实现

import java.util.LinkedList;
import java.util.List;

public class _3202{
    public static class BinaryTreeNode {
        int value;
        BinaryTreeNode left;
        BinaryTreeNode right;
        public BinaryTreeNode(){
        }
        public BinaryTreeNode(int value){
            this.value = value;
        }
    }

    public static void print(BinaryTreeNode root) {
        if (root == null) {
            return;
        }
        List<BinaryTreeNode> current = new LinkedList<>();
        List<BinaryTreeNode> reverse = new LinkedList<>();
        int flag = 0;//bool flag = false;
        BinaryTreeNode node;
        current.add(root);
        while (current.size() > 0) {
            // 从最后一个开始取,相当于栈
            node = current.remove(current.size() - 1);
            System.out.print(" "+node.val);
            if (flag == 0) {// if (!flag )   // 当前是从左往右打印的,那就按从左往右入栈
                if (node.left != null) {
                    reverse.add(node.left);
                }
                if (node.right != null) {
                    reverse.add(node.right);
                }
            }else { // 当前是从右往左打印的,那就按从右往左入栈
                if (node.right != null) {
                    reverse.add(node.right);
                }
                if (node.left != null) {
                    reverse.add(node.left);
                }
            }
            if (current.size() == 0) {//当前层处理完了
                flag = 1 - flag;//flag != ;
                List<BinaryTreeNode> tmp = current;
                current = reverse;
                reverse = tmp;
                System.out.println();
            }
        }
    }

    public static void main(String[] args) {
        //       8
        //    /    \
        //   6     10
        //  / \   / \
        // 5   7 9  11
        BinaryTreeNode n1 = new BinaryTreeNode(8);
        BinaryTreeNode n2 = new BinaryTreeNode(6);
        BinaryTreeNode n3 = new BinaryTreeNode(10);
        BinaryTreeNode n4 = new BinaryTreeNode(5);
        BinaryTreeNode n5 = new BinaryTreeNode(7);
        BinaryTreeNode n6 = new BinaryTreeNode(9);
        BinaryTreeNode n7 = new BinaryTreeNode(11);
        n1.left = n2;
        n1.right = n3;
        n2.left = n4;
        n2.right = n5;
        n3.left = n6;
        n3.right = n7;
        print(n1);
    }
}
之字形打印二叉树

相关文章

网友评论

      本文标题:32:从上到下打印二叉树

      本文链接:https://www.haomeiwen.com/subject/chxopftx.html