Search code examples
javabinary-search-tree

How to print binary search tree in nice diagram?


I have to implement binary search tree with method that prints nice diagram with connections like this:

enter image description here

For now I managed to print this:

enter image description here

However I'm struggling to make it better :/

Do you have any hints how to fix that?

It's my code of instance implementing it:

public interface PrintableTree {

    class Node {
        int data;
        Node left, right;

        Node(int data) {
            this.data = data;
            this.left = null;
            this.right = null;
        }
    }

    class Trunk {
        Trunk prev;
        String str;

        Trunk(Trunk prev, String str) {
            this.prev = prev;
            this.str = str;
        }
    }

    Node insert_Recursive(Node root, int key);

    void add(int i);

    String prettyPrint();

    static PrintableTree getInstance() {
        return new PrintableTree() {
            String stringOfTree = "";
            static final int COUNT = 2;
            Node root;

            @Override
            public void add(int i) {
                root = insert_Recursive(root, i);
            }

            @Override
            public Node insert_Recursive(Node root, int key) {
                if (root == null) {
                    root = new Node(key);
                    return root;
                }

                if (key < root.data)
                    root.left = insert_Recursive(root.left, key);
                else if (key > root.data)
                    root.right = insert_Recursive(root.right, key);

                return root;
            }

            @Override
            public String prettyPrint() {
                printTree(root, null, false);
                return "";
            }

            public void showTrunks(Trunk p) {
                if (p == null) {
                    return;
                }

                showTrunks(p.prev);
                System.out.print(p.str);
            }

            public void printTree(Node root, Trunk prev, boolean isLeft) {
                if (root == null) {
                    return;
                }

                String prev_str = "    ";
                Trunk trunk = new Trunk(prev, prev_str);

                printTree(root.left, trunk, true);

                if (prev == null) {
                    trunk.str = "";
                } else if (isLeft) {
                    trunk.str = "┌";
                    prev_str = "    │";
                } else {
                    trunk.str = "└";
                    prev.str = prev_str;
                }

                showTrunks(trunk);
                System.out.println(" " + root.data);

                if (prev != null) {
                    prev.str = prev_str;
                }
                trunk.str = "   │";

                printTree(root.right, trunk, false);
            }

        };
    }
}

Solution

  • You could use these functions. They return a string, so it is up to the caller to print it.

    I also find it nicer when the right subtree is printed upwards, and the left subtree downwards. That way, the tree is just rotated 90° from how it is usually depicted -- with the root at the top.

    Here is the relevant code:

        public String pretty() {
            return pretty(root, "", 1);
        }
    
        private String pretty(Node root, String prefix, int dir) {
            if (root == null) {
                return "";
            }
    
            String space = " ".repeat(("" + root.data).length());
            return pretty(root.right, prefix + "│  ".charAt(dir) + space, 2)
                + prefix + "└ ┌".charAt(dir) + root.data
                  + " ┘┐┤".charAt((root.left  != null ? 2 : 0) 
                                + (root.right != null ? 1 : 0)) + "\n"
                + pretty(root.left, prefix + "  │".charAt(dir) + space, 0);
        }