为了账号安全,请及时绑定邮箱和手机立即绑定

如何打印二叉树图?

如何打印二叉树图?

潇湘沐 2019-07-31 14:31:33
如何打印二叉树图?如何在Java中打印二叉树,以便输出如下:   4   / \  2   5 我的节点:public class Node<A extends Comparable> {    Node<A> left, right;    A data;    public Node(A data){        this.data = data;    }}
查看完整描述

3 回答

?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

我已经创建了简单的二叉树打印机。您可以根据需要使用和修改它,但无论如何它都没有进行优化。我认为这里可以改进很多东西;)

import java.util.ArrayList;import java.util.Collections;import java.util.List;public class BTreePrinterTest {

    private static Node<Integer> test1() {
        Node<Integer> root = new Node<Integer>(2);
        Node<Integer> n11 = new Node<Integer>(7);
        Node<Integer> n12 = new Node<Integer>(5);
        Node<Integer> n21 = new Node<Integer>(2);
        Node<Integer> n22 = new Node<Integer>(6);
        Node<Integer> n23 = new Node<Integer>(3);
        Node<Integer> n24 = new Node<Integer>(6);
        Node<Integer> n31 = new Node<Integer>(5);
        Node<Integer> n32 = new Node<Integer>(8);
        Node<Integer> n33 = new Node<Integer>(4);
        Node<Integer> n34 = new Node<Integer>(5);
        Node<Integer> n35 = new Node<Integer>(8);
        Node<Integer> n36 = new Node<Integer>(4);
        Node<Integer> n37 = new Node<Integer>(5);
        Node<Integer> n38 = new Node<Integer>(8);

        root.left = n11;
        root.right = n12;

        n11.left = n21;
        n11.right = n22;
        n12.left = n23;
        n12.right = n24;

        n21.left = n31;
        n21.right = n32;
        n22.left = n33;
        n22.right = n34;
        n23.left = n35;
        n23.right = n36;
        n24.left = n37;
        n24.right = n38;

        return root;
    }

    private static Node<Integer> test2() {
        Node<Integer> root = new Node<Integer>(2);
        Node<Integer> n11 = new Node<Integer>(7);
        Node<Integer> n12 = new Node<Integer>(5);
        Node<Integer> n21 = new Node<Integer>(2);
        Node<Integer> n22 = new Node<Integer>(6);
        Node<Integer> n23 = new Node<Integer>(9);
        Node<Integer> n31 = new Node<Integer>(5);
        Node<Integer> n32 = new Node<Integer>(8);
        Node<Integer> n33 = new Node<Integer>(4);

        root.left = n11;
        root.right = n12;

        n11.left = n21;
        n11.right = n22;

        n12.right = n23;
        n22.left = n31;
        n22.right = n32;

        n23.left = n33;

        return root;
    }

    public static void main(String[] args) {

        BTreePrinter.printNode(test1());
        BTreePrinter.printNode(test2());

    }}class Node<T extends Comparable<?>> {
    Node<T> left, right;
    T data;

    public Node(T data) {
        this.data = data;
    }}class BTreePrinter {

    public static <T extends Comparable<?>> void printNode(Node<T> root) {
        int maxLevel = BTreePrinter.maxLevel(root);

        printNodeInternal(Collections.singletonList(root), 1, maxLevel);
    }

    private static <T extends Comparable<?>> void printNodeInternal(List<Node<T>> nodes, int level, int maxLevel) {
        if (nodes.isEmpty() || BTreePrinter.isAllElementsNull(nodes))
            return;

        int floor = maxLevel - level;
        int endgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0)));
        int firstSpaces = (int) Math.pow(2, (floor)) - 1;
        int betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1;

        BTreePrinter.printWhitespaces(firstSpaces);

        List<Node<T>> newNodes = new ArrayList<Node<T>>();
        for (Node<T> node : nodes) {
            if (node != null) {
                System.out.print(node.data);
                newNodes.add(node.left);
                newNodes.add(node.right);
            } else {
                newNodes.add(null);
                newNodes.add(null);
                System.out.print(" ");
            }

            BTreePrinter.printWhitespaces(betweenSpaces);
        }
        System.out.println("");

        for (int i = 1; i <= endgeLines; i++) {
            for (int j = 0; j < nodes.size(); j++) {
                BTreePrinter.printWhitespaces(firstSpaces - i);
                if (nodes.get(j) == null) {
                    BTreePrinter.printWhitespaces(endgeLines + endgeLines + i + 1);
                    continue;
                }

                if (nodes.get(j).left != null)
                    System.out.print("/");
                else
                    BTreePrinter.printWhitespaces(1);

                BTreePrinter.printWhitespaces(i + i - 1);

                if (nodes.get(j).right != null)
                    System.out.print("\\");
                else
                    BTreePrinter.printWhitespaces(1);

                BTreePrinter.printWhitespaces(endgeLines + endgeLines - i);
            }

            System.out.println("");
        }

        printNodeInternal(newNodes, level + 1, maxLevel);
    }

    private static void printWhitespaces(int count) {
        for (int i = 0; i < count; i++)
            System.out.print(" ");
    }

    private static <T extends Comparable<?>> int maxLevel(Node<T> node) {
        if (node == null)
            return 0;

        return Math.max(BTreePrinter.maxLevel(node.left), BTreePrinter.maxLevel(node.right)) + 1;
    }

    private static <T> boolean isAllElementsNull(List<T> list) {
        for (Object object : list) {
            if (object != null)
                return false;
        }

        return true;
    }}

输出1:

         2               
        / \       
       /   \      
      /     \     
     /       \    
     7       5       
    / \     / \   
   /   \   /   \  
   2   6   3   6   
  / \ / \ / \ / \ 
  5 8 4 5 8 4 5 8

输出2:

       2               
      / \       
     /   \      
    /     \     
   /       \    
   7       5       
  / \       \   
 /   \       \  
 2   6       9   
    / \     /   
    5 8     4


查看完整回答
反对 回复 2019-07-31
?
德玛西亚99

TA贡献1770条经验 获得超3个赞

我为此做了一个改进的算法,它可以很好地处理不同大小的节点。它使用线条自上而下打印。


package alg;


import java.util.ArrayList;

import java.util.List;



/**

 * Binary tree printer

 * 

 * @author MightyPork

 */

public class TreePrinter

{

    /** Node that can be printed */

    public interface PrintableNode

    {

        /** Get left child */

        PrintableNode getLeft();



        /** Get right child */

        PrintableNode getRight();



        /** Get text to be printed */

        String getText();

    }



    /**

     * Print a tree

     * 

     * @param root

     *            tree root node

     */

    public static void print(PrintableNode root)

    {

        List<List<String>> lines = new ArrayList<List<String>>();


        List<PrintableNode> level = new ArrayList<PrintableNode>();

        List<PrintableNode> next = new ArrayList<PrintableNode>();


        level.add(root);

        int nn = 1;


        int widest = 0;


        while (nn != 0) {

            List<String> line = new ArrayList<String>();


            nn = 0;


            for (PrintableNode n : level) {

                if (n == null) {

                    line.add(null);


                    next.add(null);

                    next.add(null);

                } else {

                    String aa = n.getText();

                    line.add(aa);

                    if (aa.length() > widest) widest = aa.length();


                    next.add(n.getLeft());

                    next.add(n.getRight());


                    if (n.getLeft() != null) nn++;

                    if (n.getRight() != null) nn++;

                }

            }


            if (widest % 2 == 1) widest++;


            lines.add(line);


            List<PrintableNode> tmp = level;

            level = next;

            next = tmp;

            next.clear();

        }


        int perpiece = lines.get(lines.size() - 1).size() * (widest + 4);

        for (int i = 0; i < lines.size(); i++) {

            List<String> line = lines.get(i);

            int hpw = (int) Math.floor(perpiece / 2f) - 1;


            if (i > 0) {

                for (int j = 0; j < line.size(); j++) {


                    // split node

                    char c = ' ';

                    if (j % 2 == 1) {

                        if (line.get(j - 1) != null) {

                            c = (line.get(j) != null) ? '┴' : '┘';

                        } else {

                            if (j < line.size() && line.get(j) != null) c = '└';

                        }

                    }

                    System.out.print(c);


                    // lines and spaces

                    if (line.get(j) == null) {

                        for (int k = 0; k < perpiece - 1; k++) {

                            System.out.print(" ");

                        }

                    } else {


                        for (int k = 0; k < hpw; k++) {

                            System.out.print(j % 2 == 0 ? " " : "─");

                        }

                        System.out.print(j % 2 == 0 ? "┌" : "┐");

                        for (int k = 0; k < hpw; k++) {

                            System.out.print(j % 2 == 0 ? "─" : " ");

                        }

                    }

                }

                System.out.println();

            }


            // print line of numbers

            for (int j = 0; j < line.size(); j++) {


                String f = line.get(j);

                if (f == null) f = "";

                int gap1 = (int) Math.ceil(perpiece / 2f - f.length() / 2f);

                int gap2 = (int) Math.floor(perpiece / 2f - f.length() / 2f);


                // a number

                for (int k = 0; k < gap1; k++) {

                    System.out.print(" ");

                }

                System.out.print(f);

                for (int k = 0; k < gap2; k++) {

                    System.out.print(" ");

                }

            }

            System.out.println();


            perpiece /= 2;

        }

    }

}

要将它用于您的树,请让您的Node类实现PrintableNode。


示例输出:


                                         2952:0                                             

                    ┌───────────────────────┴───────────────────────┐                       

                 1249:-1                                         5866:0                     

        ┌───────────┴───────────┐                       ┌───────────┴───────────┐           

     491:-1                  1572:0                  4786:1                  6190:0         

  ┌─────┘                                               └─────┐           ┌─────┴─────┐     

339:0                                                      5717:0      6061:0      6271:0   


查看完整回答
反对 回复 2019-07-31
  • 3 回答
  • 0 关注
  • 1373 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号