बाइनरी ट्री आरेख कैसे प्रिंट करें?


163

मैं जावा में एक बाइनरी ट्री कैसे प्रिंट कर सकता हूं ताकि आउटपुट जैसा हो:

   4 
  / \ 
 2   5 

मेरा नोड:

public class Node<A extends Comparable> {
    Node<A> left, right;
    A data;

    public Node(A data){
        this.data = data;
    }
}

5
यह एक मुश्किल है। मुझे लगता है कि आपको पहले पेड़ की गहराई निर्धारित करनी होगी। निजी तौर पर, मैं बस नोड ग्राफ को ग्राफविज़ में डंप करूँगा और इसे इससे निपटने दूंगा। :-)
सर्वव्यापी

ऐसा लगता है कि यदि आपके पास बहुत सारे तत्व हैं, तो रूट तत्व में एक बड़ा किनारा होगा।

मेरे पास पेड़ में एक गेटडिप () विधि है
तियान

1
सिर्फ इसलिए कि विचार ने मुझे चकित कर दिया, मैंने सी ++ में कोड लिखा और इसे ग्राफविज़ डिग्राफ प्रारूप से बाहर कर दिया। खूबसूरती से तैयार किए गए पेड़।
सर्वव्यापी

जवाबों:


238

मैंने सरल बाइनरी ट्री प्रिंटर बनाया है। आप इसका उपयोग और संशोधित कर सकते हैं जैसा आप चाहते हैं, लेकिन यह वैसे भी अनुकूलित नहीं है। मुझे लगता है कि यहां बहुत सारी चीजों में सुधार किया जा सकता है;)

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   

1
इस आउटपुट को क्षैतिज में कैसे बदलें?
जिजेश अज ०

क्षैतिज उत्पादन के लिए वास्या नोविकोव के समाधान का उपयोग करना बेहतर है।
माइकेल.क्रूज़मैन

3
यह बहुत अच्छा होगा अगर आप पहली जगह के रूप में 2 ^ n - 1 चुनने पर विस्तृत कर सकते हैं और 2 ^ (n + 1) - 1 के बीच रिक्त स्थान
डीजे '

यह संतुलित पेड़ों के लिए अच्छा है क्योंकि मैंने इसे 15 मानों के दाहिने तिरछे पेड़ों में से एक के लिए आज़माया था और यह प्रिंट देखने के लिए बहुत असहनीय हो गया था।
आखिल_मित्तल

3
मेरा पेड़ 44 परतों वाला है, इसलिए 8796093022207 व्हॉट्सएप प्रिंट करने की कोशिश करने पर जावा क्रैश हो जाता है। इसलिए चेतावनी दी जाए।
सीएक्स गेमर

286

लाइनों द्वारा एक [बड़े] पेड़ को प्रिंट करें।

आउटपुट उदाहरण:

z
├── c
   ├── a
   └── b
├── d
├── e
   └── asdf
└── f

कोड:

public class TreeNode {

    final String name;
    final List<TreeNode> children;

    public TreeNode(String name, List<TreeNode> children) {
        this.name = name;
        this.children = children;
    }

    public String toString() {
        StringBuilder buffer = new StringBuilder(50);
        print(buffer, "", "");
        return buffer.toString();
    }

    private void print(StringBuilder buffer, String prefix, String childrenPrefix) {
        buffer.append(prefix);
        buffer.append(name);
        buffer.append('\n');
        for (Iterator<TreeNode> it = children.iterator(); it.hasNext();) {
            TreeNode next = it.next();
            if (it.hasNext()) {
                next.print(buffer, childrenPrefix + "├── ", childrenPrefix + "│   ");
            } else {
                next.print(buffer, childrenPrefix + "└── ", childrenPrefix + "    ");
            }
        }
    }
}

PS यह उत्तर "बाइनरी" पेड़ों पर बिल्कुल ध्यान केंद्रित नहीं करता है - इसके बजाय, यह सभी प्रकार के पेड़ों को प्रिंट करता है। समाधान लिनक्स में "पेड़" कमांड से प्रेरित है।


क्या यह समाधान सही तिरछी बाइनरी पेड़ों को संभालता है?
पेटेंट

@VasyaNovikov children.get(children.size() - 1)अगर बच्चों के लिए हैशपॉप का इस्तेमाल किया गया तो आप फिर से कैसे लिखेंगे ? मैं हर दूसरे हिस्से को संशोधित करने में कामयाब रहा लेकिन यह एक।
ले न्गुयेन

@LeNguyenDuyAnh हालांकि, HashMap ने किस प्रकार के हस्ताक्षर प्रस्तावित किए हैं? HashMap<String, List<String>>?
वासिलीनोविकोव

मैंने अपने पेड़ को लागू किया है HashMap<String, Node>। स्ट्रिंग नोड की आईडी है।
ले न्गुयेन

मैंने वास्तव में पाठ-वृक्ष नामक एक छोटे से जावा पुस्तकालय में कुछ इसी तरह से लागू किया । शायद यह किसी की मदद करे।
बारफूिन

47

मैंने इसके लिए एक बेहतर एल्गोरिथ्म बनाया है, जो अलग-अलग आकार के साथ अच्छी तरह से नोड्स को संभालता है। यह लाइनों का उपयोग करके ऊपर-नीचे प्रिंट करता है।

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   

मैं "चयनित उत्तर" तकनीक को दोहराने की कोशिश कर रहा था। लेकिन मुझे लगता है कि यह एक सबसे अच्छा जवाब है। इसलिए मजबूत और संक्षिप्त।
विक्रांत गोयल

इसे लागू करने के बाद यह बहुत अच्छा काम करता है, लेकिन केवल संतुलित पेड़ों के लिए। असंतुलित कुछ भी अजीब परिणाम देता है।
मितब्बिप सिप

मैं ???????????नोड्स के बीच की लाइनों के बजाय मिलता हूं, लेकिन बस कुछ UTF8 ans सामान समस्या होनी चाहिए। वैसे भी, महान सामान, मुझे कहना होगा। मेरे लिए सबसे अच्छा जवाब क्योंकि यह वास्तव में उपयोग करने में आसान है।
फिट्ज

हाँ, यह बात थी। बस आपको अपनी लाइनों और रिक्त स्थान पैराग्राफ के सभी विशेष वर्णों को बदलना होगा ।
फिट्ज

अच्छा, तत्वों की एक सरणी मुद्रण का समर्थन करने के लिए, एक बनाया सार जो सिर्फ इतना है कि करता है पेड़ मुद्रण के लिए @MightyPork तर्क का उपयोग कर। देखेंpublic static <T> void print(T[] elems)
नव

40
public static class Node<T extends Comparable<T>> {
    T value;
    Node<T> left, right;

    public void insertToTree(T v) {
        if (value == null) {
            value = v;
            return;
        }
        if (v.compareTo(value) < 0) {
            if (left == null) {
                left = new Node<T>();
            }
            left.insertToTree(v);
        } else {
            if (right == null) {
                right = new Node<T>();
            }
            right.insertToTree(v);
        }
    }

    public void printTree(OutputStreamWriter out) throws IOException {
        if (right != null) {
            right.printTree(out, true, "");
        }
        printNodeValue(out);
        if (left != null) {
            left.printTree(out, false, "");
        }
    }
    private void printNodeValue(OutputStreamWriter out) throws IOException {
        if (value == null) {
            out.write("<null>");
        } else {
            out.write(value.toString());
        }
        out.write('\n');
    }
    // use string and not stringbuffer on purpose as we need to change the indent at each recursion
    private void printTree(OutputStreamWriter out, boolean isRight, String indent) throws IOException {
        if (right != null) {
            right.printTree(out, true, indent + (isRight ? "        " : " |      "));
        }
        out.write(indent);
        if (isRight) {
            out.write(" /");
        } else {
            out.write(" \\");
        }
        out.write("----- ");
        printNodeValue(out);
        if (left != null) {
            left.printTree(out, false, indent + (isRight ? " |      " : "        "));
        }
    }

}

प्रिंट होगा:

                 /----- 20
                 |       \----- 15
         /----- 14
         |       \----- 13
 /----- 12
 |       |       /----- 11
 |       \----- 10
 |               \----- 9
8
 |               /----- 7
 |       /----- 6
 |       |       \----- 5
 \----- 4
         |       /----- 3
         \----- 2
                 \----- 1

इनपुट के लिए

8 4 12 2 6 10 14 1 3 5 7 9 11 13 20 15

यह @ अनुराग के उत्तर का एक प्रकार है - यह मुझे अतिरिक्त देखने के लिए प्रेरित कर रहा था |


यदि आप इसे 90 ° घुमा सकते हैं तो यह बहुत बढ़िया होगा।
अभिजीत सरकार

34

Vasya Novikov के जवाब से इसे और अधिक द्विआधारी बनाने के लिए अनुकूल है , और StringBuilderदक्षता के लिए उपयोग करते हैं ( Stringजावा में एक साथ वस्तुओं को आमतौर पर अक्षम है)।

public StringBuilder toString(StringBuilder prefix, boolean isTail, StringBuilder sb) {
    if(right!=null) {
        right.toString(new StringBuilder().append(prefix).append(isTail ? "│   " : "    "), false, sb);
    }
    sb.append(prefix).append(isTail ? "└── " : "┌── ").append(value.toString()).append("\n");
    if(left!=null) {
        left.toString(new StringBuilder().append(prefix).append(isTail ? "    " : "│   "), true, sb);
    }
    return sb;
}

@Override
public String toString() {
    return this.toString(new StringBuilder(), true, new StringBuilder()).toString();
}

आउटपुट:

       ┌── 7
   ┌── 6
      └── 5
└── 4
       ┌── 3
    └── 2
        └── 1
            └── 0

जब हम मूल्य डालते हैं तो यह एक पेड़ के लिए काम नहीं करता है: एक बीएसटी में 30,40,50,60,70,80। जैसा कि एक तिरछा पेड़ बनाता है। IsTail का मान तब गलत होना चाहिए जब मैंने right != nullइसे संपादित किया और परीक्षण किया, यह ठीक काम करता है।
आखिल_मित्तल

इनपुट के लिए धन्यवाद, मैंने अभी उत्तर को संपादित किया है, यह बेहतर है?
टॉड डेविस

धन्यवाद, @Vasya Novikov का उत्तर बहुत अच्छा है, लेकिन मुझे इसके लिंक लिस्ट संस्करण की आवश्यकता है, और आपका उत्तर मेरे मामले में ठीक है।
हिचौ

सभी उत्तरों में, यह सबसे अच्छा दिखने वाला पेड़ पैदा करता है, और कोड बहुत साफ है!
पी-सूरज

15

michal.kreuzman अच्छा एक मैं कहना होगा।

मैं खुद से एक कार्यक्रम बनाने के लिए आलसी महसूस कर रहा था और नेट पर कोड खोज रहा था जब मैंने पाया कि यह वास्तव में मेरी मदद करता है।

लेकिन मुझे यह देखकर डर लगता है कि यह केवल एकल अंकों के लिए काम करता है जैसे कि आप एक से अधिक अंकों का उपयोग करने जा रहे हैं, चूंकि आप रिक्त स्थान का उपयोग कर रहे हैं और टैब का नहीं कि संरचना गलत हो रही है और प्रोग्राम इसका उपयोग ढीला कर देगा।

मेरे बाद के कोड के लिए मुझे कुछ बड़े इनपुट (कम से कम 10 से अधिक) की आवश्यकता थी, यह मेरे लिए काम नहीं करता था, और नेट पर बहुत खोज करने के बाद जब मुझे कुछ भी नहीं मिला, तो मैंने खुद एक कार्यक्रम बनाया।

इसमें अभी कुछ कीड़े हैं, फिर से अभी मैं उन्हें सही करने के लिए आलसी महसूस कर रहा हूं लेकिन यह बहुत खूबसूरती से प्रिंट करता है और नोड्स किसी भी बड़े मूल्य को ले सकते हैं।

पेड़ के रूप में सवाल का उल्लेख नहीं किया जा रहा है लेकिन यह 270 डिग्री घुमाया गया है :)

public static void printBinaryTree(TreeNode root, int level){
    if(root==null)
         return;
    printBinaryTree(root.right, level+1);
    if(level!=0){
        for(int i=0;i<level-1;i++)
            System.out.print("|\t");
            System.out.println("|-------"+root.val);
    }
    else
        System.out.println(root.val);
    printBinaryTree(root.left, level+1);
}    

इस फ़ंक्शन को अपने स्वयं के निर्दिष्ट ट्रीनोड के साथ रखें और स्तर को शुरुआत में 0 पर रखें, और आनंद लें!

यहाँ कुछ नमूना आउटपुट दिए गए हैं:

|       |       |-------11
|       |-------10
|       |       |-------9
|-------8
|       |       |-------7
|       |-------6
|       |       |-------5
4
|       |-------3
|-------2
|       |-------1


|       |       |       |-------10
|       |       |-------9
|       |-------8
|       |       |-------7
|-------6
|       |-------5
4
|       |-------3
|-------2
|       |-------1

केवल समस्या विस्तारित शाखाओं के साथ है; मैं जल्द से जल्द समस्या को हल करने की कोशिश करूंगा लेकिन तब तक आप इसका भी उपयोग कर सकते हैं।


14

आपके पेड़ को प्रत्येक परत के लिए दुगुनी दूरी की आवश्यकता होगी:

       ए
      / \ _
     / \ _
    / \ _
   / \ _
   बीसी
  / \ / \
 / \ / \
 defg
/ \ / \ / \ / \
hijklmno

आप अपने पेड़ को एक सरणी में, हर गहराई के लिए एक सरणी में सहेज सकते हैं:

[[एक], [ख, ग], [डी, ई, एफ, जी], [एच, आई, जे, कश्मीर, एल, एम, एन, ओ]]

यदि आपका पेड़ भरा नहीं है, तो आपको उस सरणी में खाली मान शामिल करने की आवश्यकता है:

       ए
      / \ _
     / \ _
    / \ _
   / \ _
   बीसी
  / \ / \
 / \ / \
 defg
/ \ / \ / \
hiklmo
[[ए], [बी, सी], [डी, ई, एफ, जी], [एच, आई, के, के, एल, एम, ओ]

फिर आप अपने पेड़ को प्रिंट करने के लिए सरणी पर ओवररेट कर सकते हैं, पहले तत्व से पहले रिक्त स्थान प्रिंट कर सकते हैं और तत्वों के बीच गहराई पर निर्भर करते हुए और लाइनों को प्रिंट करते हुए निर्भर करता है कि अगली परत के लिए सरणी में संबंधित तत्व भरे हुए हैं या नहीं। यदि आपके मान एक वर्ण से अधिक लंबे हो सकते हैं, तो आपको सरणी निरूपण बनाते समय सबसे लंबा मान ज्ञात करना होगा और सभी चौड़ाई और तदनुसार लाइनों की संख्या को गुणा करना होगा।


क्या होगा अगर पेड़ पूरा नहीं है? उस स्थिति में ऐसा लगता है कि आपको प्रत्येक स्तर पर स्थान को दोगुना किए बिना ऐसा करने में सक्षम होना चाहिए।
templatetypedef

हां, लेकिन केवल कुछ बहुत ही सीमित मामलों में, जहां अधिकांश उपप्रकार एक ही स्तर से पेड़ों की बजाय नीचे की सूची से जुड़े होते हैं या आप परतों के बीच अलग-अलग रिक्ति के साथ अलग-अलग उप-आकर्षित करते हैं ...
hd42

13

मुझे एक बड़े सामान्य पेड़ को छापने के लिए वास्यानोविकोव का उत्तर बहुत उपयोगी लगा, और इसे बाइनरी ट्री के लिए संशोधित किया गया

कोड:

class TreeNode {
    Integer data = null;
    TreeNode left = null;
    TreeNode right = null;

    TreeNode(Integer data) {this.data = data;}

    public void print() {
        print("", this, false);
    }

    public void print(String prefix, TreeNode n, boolean isLeft) {
        if (n != null) {
            System.out.println (prefix + (isLeft ? "|-- " : "\\-- ") + n.data);
            print(prefix + (isLeft ? "|   " : "    "), n.left, true);
            print(prefix + (isLeft ? "|   " : "    "), n.right, false);
        }
    }
}

नमूना उत्पादन:

\-- 7
    |-- 3
    |   |-- 1
    |   |   \-- 2
    |   \-- 5
    |       |-- 4
    |       \-- 6
    \-- 11
        |-- 9
        |   |-- 8
        |   \-- 10
        \-- 13
            |-- 12
            \-- 14

8

स्काला भाषा में एक समाधान , जो मैंने जावा में लिखा था :

case class Node(name: String, children: Node*) {

    def toTree: String = toTree("", "").mkString("\n")

    private def toTree(prefix: String, childrenPrefix: String): Seq[String] = {
        val firstLine = prefix + this.name

        val firstChildren = this.children.dropRight(1).flatMap { child =>
            child.toTree(childrenPrefix + "├── ", childrenPrefix + "│   ")
        }
        val lastChild = this.children.takeRight(1).flatMap { child =>
            child.toTree(childrenPrefix + "└── ", childrenPrefix + "    ")
        }
        firstLine +: firstChildren ++: lastChild
    }

}

आउटपुट उदाहरण:

vasya
├── frosya
   ├── petya
      └── masha
   └── kolya
└── frosya2

1
लैम्ब्डा के साथ जावा में भी उपलब्ध है, शायद आप अपने जावा समाधान को अपडेट करना चाहते हैं?
टिनटिन

@ टिन्टिन स्काला केवल लैम्ब्डा कार्यों के बारे में नहीं है। लेकिन अगर आपके मन में जावा के लिए एक अच्छा सुधार है, तो "एडिट" करने के लिए स्वतंत्र महसूस करें, जिसे तब
स्टैकऑवरफ्लो

5

मुझे पता है तुम लोगों के पास सब कुछ बहुत अच्छा है; मैं सिर्फ अपना हिस्सा देना चाहता हूं - शायद यह सबसे अच्छा तरीका नहीं है, लेकिन यह खुद के लिए एकदम सही है!

के साथ pythonऔर pipपर, यह वास्तव में काफी सरल है! बूम!

मैक या उबंटू पर (मेरा मैक है)

  1. खुला टर्मिनल
  2. $ pip install drawtree
  3. $python, अजगर सांत्वना दर्ज करें; आप इसे दूसरे तरीके से कर सकते हैं
  4. from drawtree import draw_level_order
  5. draw_level_order('{2,1,3,0,7,9,1,2,#,1,0,#,#,8,8,#,#,#,#,7}')

किया हुआ!

        2
       / \
      /   \
     /     \
    1       3
   / \     / \
  0   7   9   1
 /   / \     / \
2   1   0   8   8
       /
      7

स्रोत ट्रैकिंग:

इस पोस्ट को देखने से पहले, मैं Google "बाइनरी ट्री प्लेन टेक्स्ट" गया

और मुझे यह https://www.reddit.com/r/learnpython/comments/3naiq8/draw_binary_tree_in_plain_text/ मिला , मुझे इस https://github.com/msbanik-drawtree पर निर्देशित करें


@DenysVitali ओह हाँ आप सही हैं): मुझे शायद इसे 'क्रमबद्ध स्तर के ऑर्डर ट्रैवर्सल (किसी भी भाषा / अजगर) से पेड़ को कैसे प्रिंट करना है' के लिए स्थानांतरित करना चाहिए।
सीन एल

3
मैं असभ्य दिखना नहीं चाहता था, लेकिन जब कोई उपयोगकर्ता सवाल java
Denys Vitali

3
public void printPreety() {
    List<TreeNode> list = new ArrayList<TreeNode>();
    list.add(head);
    printTree(list, getHeight(head));
}

public int getHeight(TreeNode head) {

    if (head == null) {
        return 0;
    } else {
        return 1 + Math.max(getHeight(head.left), getHeight(head.right));
    }
}

/**
 * pass head node in list and height of the tree 
 * 
 * @param levelNodes
 * @param level
 */
private void printTree(List<TreeNode> levelNodes, int level) {

    List<TreeNode> nodes = new ArrayList<TreeNode>();

    //indentation for first node in given level
    printIndentForLevel(level);

    for (TreeNode treeNode : levelNodes) {

        //print node data
        System.out.print(treeNode == null?" ":treeNode.data);

        //spacing between nodes
        printSpacingBetweenNodes(level);

        //if its not a leaf node
        if(level>1){
            nodes.add(treeNode == null? null:treeNode.left);
            nodes.add(treeNode == null? null:treeNode.right);
        }
    }
    System.out.println();

    if(level>1){        
        printTree(nodes, level-1);
    }
}

private void printIndentForLevel(int level){
    for (int i = (int) (Math.pow(2,level-1)); i >0; i--) {
        System.out.print(" ");
    }
}

private void printSpacingBetweenNodes(int level){
    //spacing between nodes
    for (int i = (int) ((Math.pow(2,level-1))*2)-1; i >0; i--) {
        System.out.print(" ");
    }
}


Prints Tree in following format:
                4                               
        3               7               
    1               5       8       
      2                       10   
                             9   

2

यह एक पेड़ को प्रिंट करने के लिए एक बहुत ही सरल उपाय है। यह बहुत सुंदर नहीं है, लेकिन यह वास्तव में सरल है:

enum { kWidth = 6 };
void PrintSpace(int n)
{
  for (int i = 0; i < n; ++i)
    printf(" ");
}

void PrintTree(struct Node * root, int level)
{
  if (!root) return;
  PrintTree(root->right, level + 1);
  PrintSpace(level * kWidth);
  printf("%d", root->data);
  PrintTree(root->left, level + 1);
}

नमूना उत्पादन:

      106
            105
104
            103
                  102
                        101
      100

2

VasyaNovikov जवाब के आधार पर। कुछ जावा मैजिक के साथ बेहतर: जेनरिक और फंक्शनल इंटरफेस।

/**
 * Print a tree structure in a pretty ASCII fromat.
 * @param prefix Currnet previx. Use "" in initial call!
 * @param node The current node. Pass the root node of your tree in initial call.
 * @param getChildrenFunc A {@link Function} that returns the children of a given node.
 * @param isTail Is node the last of its sibblings. Use true in initial call. (This is needed for pretty printing.)
 * @param <T> The type of your nodes. Anything that has a toString can be used.
 */
private <T> void printTreeRec(String prefix, T node, Function<T, List<T>> getChildrenFunc, boolean isTail) {
    String nodeName = node.toString();
    String nodeConnection = isTail ? "└── " : "├── ";
    log.debug(prefix + nodeConnection + nodeName);
    List<T> children = getChildrenFunc.apply(node);
    for (int i = 0; i < children.size(); i++) {
        String newPrefix = prefix + (isTail ? "    " : "│   ");
        printTreeRec(newPrefix, children.get(i), getChildrenFunc, i == children.size()-1);
    }
}

प्रारंभिक कॉल उदाहरण:

Function<ChecksumModel, List<ChecksumModel>> getChildrenFunc = node -> getChildrenOf(node)
printTreeRec("", rootNode, getChildrenFunc, true);

जैसे कुछ आउटपुट करेगा

└── rootNode
    ├── childNode1
    ├── childNode2
       ├── childNode2.1
       ├── childNode2.2
       └── childNode2.3
    ├── childNode3
    └── childNode4

2

मैंने जावा में एक बाइनरी ट्री प्रिंटर लिखा है।

कोड यहाँ GitHub पर है

यह रन टाइम दक्षता के लिए अनुकूलित नहीं किया गया है, लेकिन जब से हम ASCII में मुद्रण के बारे में बात कर रहे हैं, मुझे लगा कि यह बहुत बड़े पेड़ों पर इस्तेमाल नहीं होने जा रहा है। हालांकि इसमें कुछ अच्छी विशेषताएं हैं।

  1. यह अंतरिक्ष का कुशल उपयोग करता है कि एक बड़ा सबट्रेरी जितना संभव हो उतना छोटा एक के नीचे फैलता है।
  2. नोड लेबल के बीच न्यूनतम क्षैतिज स्थान सेट करने के लिए एक पैरामीटर है।
  3. नोड लेबल मनमानी लंबाई के तार होते हैं।
  4. किसी एक पेड़ की छपाई के लिए एक विधि के अलावा, आवश्यक रूप से कई पंक्तियों का उपयोग करके, पूरे पृष्ठ में क्षैतिज रूप से (पृष्ठ चौड़ाई के लिए एक पैरामीटर के साथ) पेड़ों की सूची को मुद्रित करने के लिए एक विधि है।
  5. विकर्ण शाखाओं (स्लैश और बैकस्लैश वर्णों का उपयोग करके) या क्षैतिज शाखाओं (एससीआई बॉक्स ड्राइंग वर्णों का उपयोग करके) के साथ पेड़ों को प्रिंट करने का विकल्प है। उत्तरार्द्ध अधिक कॉम्पैक्ट है और पेड़ के स्तर को अधिक स्पष्ट रूप से स्पष्ट करता है।
  6. यह काम करता हैं।

कुछ डेमो / परीक्षण कार्यक्रम शामिल हैं।

एक बेतरतीब ढंग से उत्पन्न बाइनरी ट्री का एक उदाहरण, जैसा कि कार्यक्रम द्वारा मुद्रित किया गया है, निम्नानुसार है। यह अंतरिक्ष के कुशल उपयोग का चित्रण करता है, जिसमें एक छोटे से बाएं सबट्री के नीचे एक बड़ा दाया उपप्रकार होता है:

             seven                                        
              / \                                         
             /   \                                        
            /     \                                       
           /       \                                      
          /         \                                     
         /           \                                    
       five        thirteen                               
       / \           / \                                  
      /   \         /   \                                 
     /     \       /     \                                
  three    six    /       \                               
   / \           /         \                              
  /   \         /           \                             
one   four     /             \                            
  \           /               \                           
  two        /                 \                          
           nine            twenty four                    
           / \                 / \                        
          /   \               /   \                       
         /     \             /     \                      
      eight   twelve        /       \                     
               /           /         \                    
             ten          /           \                   
               \         /             \                  
              eleven    /               \                 
                       /                 \                
                      /                   \               
                     /                     \              
                 eighteen              twenty seven       
                   / \                     / \            
                  /   \                   /   \           
                 /     \                 /     \          
                /       \               /       \         
               /         \             /         \        
              /           \           /           \       
             /             \    twenty five   twenty eight
            /               \         \             \     
           /                 \     twenty six      thirty 
       fourteen            nineteen                 /     
           \                   \              twenty nine 
         sixteen           twenty three                   
           / \                 /                          
          /   \           twenty two                      
         /     \             /                            
        /       \         twenty                          
       /         \           \                            
   fifteen    seventeen   twenty one                      

पृष्ठ पर सभी पाँच नोड बाइनरी ट्री (इन-ऑर्डर लेबल के साथ) को मुद्रित करने का एक उदाहरण:

one           one         one          one        one       one         one     
  \             \           \            \          \         \           \     
  two           two         two          two        two      three       three  
    \             \           \            \          \       / \         / \   
   three         three        four         five       five  two four    two five
      \             \         / \          /          /           \         /   
      four          five     /   \      three       four          five    four  
        \           /     three  five      \        /                           
        five      four                     four  three                          



one          one        one        one       one       one         one        two        
  \            \          \          \         \         \           \        / \        
  four         four       five       five      five      five        five    /   \       
  / \          / \        /          /         /         /           /     one  three    
two five      /   \     two        two      three      four        four            \     
  \        three  five    \          \       / \       /           /               four  
 three      /            three       four  two four  two        three                \   
          two               \        /                 \         /                   five
                            four  three               three    two                       



   two          two          two        two      three         three         three    
   / \          / \          / \        / \       / \           / \           / \     
  /   \       one four     one five   one five  one four       /   \        two four  
one  three        / \          /          /       \   \       /     \       /     \   
        \        /   \      three       four      two five  one     five  one     five
        five  three  five      \        /                     \     /                 
        /                      four  three                    two four                
      four                                                                            



   three      four      four         four         four            four       five    
    / \       / \       / \          / \          / \             / \        /       
  two five  one five  one five     two five      /   \           /   \     one       
  /   /       \         \          / \        three  five     three  five    \       
one four      two      three      /   \        /               /             two     
                \       /       one  three   one             two               \     
               three  two                      \             /                three  
                                               two         one                   \   
                                                                                 four



  five      five      five      five       five         five      five        five
  /         /         /         /          /            /         /           /   
one       one       one       one        two          two      three       three  
  \         \         \         \        / \          / \       / \         / \   
  two      three      four      four    /   \       one four  one four    two four
    \       / \       /         /     one  three        /       \         /       
    four  two four  two      three            \      three      two     one       
    /                 \       /               four                                
 three               three  two                                                   



    five      five         five        five          five
    /         /            /           /             /   
  four      four         four        four          four  
  /         /            /           /             /     
one       one          two        three         three    
  \         \          / \         /             /       
  two      three      /   \      one           two       
    \       /       one  three     \           /         
   three  two                      two       one 

निम्नलिखित एक ही पेड़ के 4 अलग-अलग तरीकों से मुद्रित उदाहरण है, 1 और 3 के क्षैतिज अंतर के साथ, और विकर्ण और क्षैतिज शाखाओं के साथ।

                   27        
             ┌─────┴─────┐   
             13          29  
      ┌──────┴──────┐  ┌─┴─┐ 
      8             23 28  30
   ┌──┴──┐       ┌──┴──┐     
   4     11      21    26    
 ┌─┴─┐  ┌┴┐    ┌─┴─┐  ┌┘     
 2   5  9 12   18  22 24     
┌┴┐  └┐ └┐   ┌─┴─┐    └┐     
1 3   6  10  17  19    25    
      └┐    ┌┘   └┐          
       7    15    20         
          ┌─┴─┐              
          14  16             


                 27        
                / \        
               /   \       
              13    29     
             / \   / \     
            /   \ 28  30   
           /     \         
          /       \        
         /         \       
        /           \      
       8             23    
      / \           / \    
     /   \         /   \   
    4     11      /     \  
   / \   / \     21      26
  2   5 9   12  / \     /  
 / \   \ \     18  22  24  
1   3   6 10  / \       \  
         \   17  19      25
          7 /     \        
           15      20      
          / \              
         14  16            


                             27            
                    ┌────────┴────────┐    
                    13                29   
          ┌─────────┴─────────┐    ┌──┴──┐ 
          8                   23   28    30
     ┌────┴────┐         ┌────┴────┐       
     4         11        21        26      
  ┌──┴──┐    ┌─┴─┐    ┌──┴──┐     ┌┘       
  2     5    9   12   18    22    24       
┌─┴─┐   └┐   └┐    ┌──┴──┐        └┐       
1   3    6    10   17    19        25      
         └┐       ┌┘     └┐                
          7       15      20               
               ┌──┴──┐                     
               14    16                    


                      27         
                     / \         
                    /   \        
                   /     \       
                  /       \      
                 13        29    
                / \       / \    
               /   \     /   \   
              /     \   28    30 
             /       \           
            /         \          
           /           \         
          /             \        
         /               \       
        8                 23     
       / \               / \     
      /   \             /   \    
     /     \           /     \   
    4       11        /       \  
   / \     / \       21        26
  2   5   9   12    / \       /  
 / \   \   \       /   \     24  
1   3   6   10    18    22    \  
         \       / \           25
          7     /   \            
               17    19          
              /       \          
             15        20        
            / \                  
           /   \                 
          14    16               

यह अच्छा है कि आपने इस परियोजना को प्रकाशित किया। ऐसा लगता है कि यह एक अच्छा काम करता है, लेकिन मूल रूप से स्टैक ओवरफ्लो पर एक अच्छे उत्तर के लिए आपकी लाइब्रेरी की एक कड़ी ही नहीं बनती है। कम से कम, आपको अपने द्वारा दिए गए उदाहरणों को प्रदर्शित करने के लिए अपनी लाइब्रेरी का उपयोग करने के लिए आवश्यक कोड शामिल करना चाहिए, ताकि लोगों को पता चले कि आपके पुस्तकालय का उपयोग करने में क्या शामिल है। अभी, यह आपके GitHub रेपो के लिए केवल एक विज्ञापन है। यह एक बुरी बात नहीं है, यदि आप लोगों को दिखा रहे हैं कि वास्तव में इसका उपयोग कैसे किया जाए।
Makyen

BTW: यदि आप उदाहरण कोड में संपादित करते हैं, तो कृपया मुझे @Makyenएक टिप्पणी में शामिल करके यहाँ पिंग करें ।
Makyen

2

यह एक दिलचस्प सवाल है, और मैंने इसके लिए एक परियोजना भी लिखी है।

द्विआधारी पेड़-प्रिंटर

यहाँ कुछ उदाहरण हैं:

यादृच्छिक BST प्रिंट करें।

BTPrinter.printRandomBST(100, 100);
                              38                                  
                              / \                                 
                             /   \                                
                            /     \                               
                           /       \                              
                          /         \                             
                         /           \                            
                        /             \                           
                       /               \                          
                      /                 \                         
                     /                   \                        
                    /                     \                       
                   /                       \                      
                  /                         \                     
                 /                           \                    
                /                             \                   
               /                               \                  
              28                               82                 
             / \                               / \                
            /   \                             /   \               
           /     \                           /     \              
          /       \                         /       \             
         5        31                       /         \            
        / \       / \                     /           \           
       /   \     30 36                   /             \          
      /     \   /   / \                 /               \         
     /       \ 29  33 37               /                 \        
    /         \   / \                 /                   \       
   /           \ 32 35               65                   95      
  1            14   /               / \                   / \     
 / \           / \ 34              /   \                 94 97    
0   2         /   \               /     \               /   / \   
     \       12   24             /       \             93  96 98  
      3     / \   / \           /         \           /         \ 
       \   9  13 16 25         /           \         84         99
        4 / \   / \   \       /             \       / \           
         7  10 15 23  26     59             74     83 86          
        / \   \   /     \   / \             / \       / \         
       6   8  11 22     27 56 60           73 76     85 91        
                /         / \   \         /   / \       / \       
               20        /   \  61       67  75 79     88 92      
              / \       40   58   \     / \     / \   / \         
             18 21     / \   /    62   66 72   78 80 87 89        
            / \       39 54 57      \     /   /     \     \       
           17 19         / \        64   69  77     81    90      
                        50 55       /   / \                       
                       / \         63  68 70                      
                      /   \                 \                     
                     /     \                71                    
                    47     53                                     
                   / \     /                                      
                  /   \   52                                      
                 42   49 /                                        
                / \   / 51                                        
               41 43 48                                           
                    \                                             
                    46                                            
                    /                                             
                   45                                             
                  /                                               
                 44     

लेटकोड-शैली स्तर के ऑर्डर सरणी से प्रिंट ट्री, '#' का अर्थ है एक पथ प्रदर्शक, जहां कोई नोड नीचे मौजूद नहीं है।

BTPrinter.printTree("1,2,3,4,5,#,#,6,7,8,1,#,#,#,#,#,#,2,3,4,5,6,7,8,9,10,11,12,13,14,15");
        1              
       / \             
      2   3            
     / \               
    /   \              
   4     5             
  / \   / \            
 6   7 8   1           
          / \          
         /   \         
        /     \        
       /       \       
      /         \      
     2           3     
    / \         / \    
   /   \       /   \   
  4     5     6     7  
 / \   / \   / \   / \ 
8   9 10 11 12 13 14 15

1

मुझे अपनी एक परियोजना में एक बाइनरी ट्री प्रिंट करने की आवश्यकता थी, इसके लिए मैंने एक जावा वर्ग तैयार किया है TreePrinter, जिसमें से एक नमूना आउटपुट है:

                [+]
               /   \
              /     \
             /       \
            /         \
           /           \
        [*]             \
       /   \             [-]
[speed]     [2]         /   \
                    [45]     [12]

यहाँ क्लास TreePrinterके साथ-साथ क्लास के लिए भी कोड है TextNode। किसी भी पेड़ की छपाई के लिए आप सिर्फ TextNodeकक्षा के साथ एक बराबर पेड़ बना सकते हैं ।


import java.util.ArrayList;

public class TreePrinter {

    public TreePrinter(){
    }

    public static String TreeString(TextNode root){
        ArrayList layers = new ArrayList();
        ArrayList bottom = new ArrayList();

        FillBottom(bottom, root);  DrawEdges(root);

        int height = GetHeight(root);
        for(int i = 0; i  s.length()) min = s.length();

            if(!n.isEdge) s += "[";
            s += n.text;
            if(!n.isEdge) s += "]";

            layers.set(n.depth, s);
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i  temp = new ArrayList();

            for(int i = 0; i  0) temp.get(i-1).left = x;
                temp.add(x);
            }

            temp.get(count-1).left = n.left;
            n.left.depth = temp.get(count-1).depth+1;
            n.left = temp.get(0);

            DrawEdges(temp.get(count-1).left);
        }
        if(n.right != null){
            int count = n.right.x - (n.x + n.text.length() + 2);
            ArrayList temp = new ArrayList();

            for(int i = 0; i  0) temp.get(i-1).right = x;
                temp.add(x);
            }

            temp.get(count-1).right = n.right;
            n.right.depth = temp.get(count-1).depth+1;
            n.right = temp.get(0);  

            DrawEdges(temp.get(count-1).right);
        }
    }

    private static void FillBottom(ArrayList bottom, TextNode n){
        if(n == null) return;

        FillBottom(bottom, n.left);

        if(!bottom.isEmpty()){            
            int i = bottom.size()-1;
            while(bottom.get(i).isEdge) i--;
            TextNode last = bottom.get(i);

            if(!n.isEdge) n.x = last.x + last.text.length() + 3;
        }
        bottom.add(n);
        FillBottom(bottom, n.right);
    }

    private static boolean isLeaf(TextNode n){
        return (n.left == null && n.right == null);
    }

    private static int GetHeight(TextNode n){
        if(n == null) return 0;

        int l = GetHeight(n.left);
        int r = GetHeight(n.right);

        return Math.max(l, r) + 1;
    }
}


class TextNode {
    public String text;
    public TextNode parent, left, right;
    public boolean isEdge;
    public int x, depth;

    public TextNode(String text){
        this.text = text;
        parent = null; left = null; right = null;
        isEdge = false;
        x = 0; depth = 0;
    }
}

अंत में यहां दिए गए नमूने की छपाई के लिए एक परीक्षण वर्ग है:


public class Test {

    public static void main(String[] args){
        TextNode root = new TextNode("+");
        root.left = new TextNode("*");            root.left.parent = root;
        root.right = new TextNode("-");           root.right.parent = root;
        root.left.left = new TextNode("speed");   root.left.left.parent = root.left;
        root.left.right = new TextNode("2");      root.left.right.parent = root.left;
        root.right.left = new TextNode("45");     root.right.left.parent = root.right;
        root.right.right = new TextNode("12");    root.right.right.parent = root.right;

        System.out.println(TreePrinter.TreeString(root));
    }
}

1

आप बहुत आसानी से कल्पना करने के लिए एक एप्लेट का उपयोग कर सकते हैं। आपको निम्नलिखित वस्तुओं को प्रिंट करने की आवश्यकता है।

  1. कुछ दृश्यमान त्रिज्या के साथ मंडलियों के रूप में नोड्स प्रिंट करें

    • प्रत्येक नोड के लिए निर्देशांक प्राप्त करें।

    • एक्स कोऑर्डिनेट को कल्पना की जा सकती है क्योंकि नोड से पहले नोड्स की संख्या का पता लगाया जाता है, जो इसके इनवर्टर ट्रैवर्सल में देखा जाता है।

    • Y समन्वय को विशेष नोड की गहराई के रूप में देखा जा सकता है।


  1. माता-पिता और बच्चों के बीच की पंक्तियों को प्रिंट करें

    • यह नोड्स के x और y निर्देशांक और प्रत्येक नोड के माता-पिता को अलग-अलग सूचियों में बनाए रखकर किया जा सकता है।

    • रूट को छोड़कर प्रत्येक नोड के लिए प्रत्येक नोड को उसके माता-पिता के साथ x और y दोनों बच्चे और माता-पिता के निर्देशांक के साथ जोड़ते हैं।


क्या आप कल्पना कर सकते हैं और मौजूदा उत्तरों की तुलना में बेहतर समाधान दे सकते हैं?
इनामुल हसन

1
private StringBuilder prettyPrint(Node root, int currentHeight, int totalHeight) {
        StringBuilder sb = new StringBuilder();
        int spaces = getSpaceCount(totalHeight-currentHeight + 1);
        if(root == null) {
            //create a 'spatial' block and return it
            String row = String.format("%"+(2*spaces+1)+"s%n", "");
            //now repeat this row space+1 times
            String block = new String(new char[spaces+1]).replace("\0", row);
            return new StringBuilder(block);
        }
        if(currentHeight==totalHeight) return new StringBuilder(root.data+"");
        int slashes = getSlashCount(totalHeight-currentHeight +1);
        sb.append(String.format("%"+(spaces+1)+"s%"+spaces+"s", root.data+"", ""));
        sb.append("\n");
        //now print / and \
        // but make sure that left and right exists
        char leftSlash = root.left == null? ' ':'/';
        char rightSlash = root.right==null? ' ':'\\';
        int spaceInBetween = 1;
        for(int i=0, space = spaces-1; i<slashes; i++, space --, spaceInBetween+=2) {
            for(int j=0; j<space; j++) sb.append(" ");
            sb.append(leftSlash);
            for(int j=0; j<spaceInBetween; j++) sb.append(" ");
            sb.append(rightSlash+"");
            for(int j=0; j<space; j++) sb.append(" ");
            sb.append("\n");
        }
        //sb.append("\n");

        //now get string representations of left and right subtrees
        StringBuilder leftTree = prettyPrint(root.left, currentHeight+1, totalHeight);
        StringBuilder rightTree = prettyPrint(root.right, currentHeight+1, totalHeight);
        // now line by line print the trees side by side
        Scanner leftScanner = new Scanner(leftTree.toString());
        Scanner rightScanner = new Scanner(rightTree.toString());
//      spaceInBetween+=1;
        while(leftScanner.hasNextLine()) {
            if(currentHeight==totalHeight-1) {
                sb.append(String.format("%-2s %2s", leftScanner.nextLine(), rightScanner.nextLine()));
                sb.append("\n");
                spaceInBetween-=2;              
            }
            else {
                sb.append(leftScanner.nextLine());
                sb.append(" ");
                sb.append(rightScanner.nextLine()+"\n");
            }
        }

        return sb;

    }
private int getSpaceCount(int height) {
        return (int) (3*Math.pow(2, height-2)-1);
    }
private int getSlashCount(int height) {
        if(height <= 3) return height -1;
        return (int) (3*Math.pow(2, height-3)-1);
    }

https://github.com/murtraja/java-binary-tree-printer

केवल 1 से 2 अंकों के पूर्णांक के लिए काम करता है (मैं इसे सामान्य बनाने के लिए आलसी था)

विषम पूर्ण


1

क्षैतिज दृश्य के लिए यह सबसे सरल उपाय था। उदाहरणों के गुच्छा के साथ प्रयास किया। मेरे उद्देश्य के लिए अच्छी तरह से काम करता है। @ नाइटिन-के के उत्तर से अपडेट किया गया।

public void print(String prefix, BTNode n, boolean isLeft) {
    if (n != null) {
        print(prefix + "     ", n.right, false);
        System.out.println (prefix + ("|-- ") + n.data);
        print(prefix + "     ", n.left, true);
    }
}

कॉल करें:

bst.print("", bst.root, false);

उपाय:

                         |-- 80
                    |-- 70
               |-- 60
          |-- 50
     |-- 40
|-- 30
     |-- 20
          |-- 10

1
  1. आपको अपने पेड़ को पार करने के लिए लेवल ऑर्डर करना होगा ।
  2. नोड लंबाई और अंतरिक्ष लंबाई चुनें ।
  3. प्रत्येक स्तर के सापेक्ष वृक्ष की आधार चौड़ाई प्राप्त करें जो है ।node_length * nodes_count + space_length * spaces_count*
  4. ब्रांचिंग, रिक्ति, इंडेंटेशन और गणना की गई आधार चौड़ाई के बीच एक संबंध खोजें।

GitHub पर कोड: YoussefRaafatNasry / bst-ascii-visualization

                                             07                     
                                             /\                     
                                            /  \                    
                                           /    \                   
                                          /      \                  
                                         /        \                 
                                        /          \                
                                       /            \               
                                      /              \              
                                     /                \             
                                    /                  \            
                                   /                    \           
                                 03                      11         
                                 /\                      /\         
                                /  \                    /  \        
                               /    \                  /    \       
                              /      \                /      \      
                             /        \              /        \     
                           01          05          09          13   
                           /\          /\          /\          /\   
                          /  \        /  \        /  \        /  \  
                        00    02    04    06    08    10    12    14

मैं कहता हूं कि कोड इतना छोटा है कि आप इसे अपने उत्तर में एम्बेड कर सकते हैं।
m02ph3u5

कोड केवल visualizeफ़ंक्शन नहीं है, यह पूरी visualizerकक्षा है जो हेडर फ़ाइल सहित लगभग 200 स्थान है।
युसफेफराफातनासी जूल 20'19

1

उन लोगों के लिए जो जंग समाधान की तलाश में हैं:

pub struct Node {
  pub value: i32,
  left: Option<Box<Node>>,
  right: Option<Box<Node>>
}

impl Node {

  pub fn new(val: i32) -> Node {
    Node {
      value: val,
      left: None,
      right: None
    }
  }

  pub fn getLeftNode(&self) -> Option<&Node> {
   self.left.as_deref()
  }

  pub fn getRightNode(&self) -> Option<&Node> {
   self.right.as_deref()
  }

  pub fn setLeftNode(&mut self, val: i32) -> &mut Node {
   self.left = Some(Box::new(Node::new(val)));
   self.left.as_deref_mut().unwrap()
  }

  pub fn setRightNode(&mut self, val: i32) -> &mut Node {
   self.right = Some(Box::new(Node::new(val)));
   self.right.as_deref_mut().unwrap()
  }

  fn visualizeTree(&self, level: u16, is_tail: bool, columns: &mut HashSet<u16>) {
    let left = self.getLeftNode();
    let right = self.getRightNode();

    if right.is_some() {
      right.unwrap().visualizeTree(level+1, false, columns);
    }

    if level > 0 {
      for i in 0..level-1 {
          if columns.contains(&i) {
            print!("│   ");
          } else {
            print!("    ");
          }
      }
      if is_tail {
        println!("└── {}", self.value);
        columns.remove(&(level-1));
        columns.insert(level);
      } else {
        println!("┌── {}", self.value);
        columns.insert(level);
        columns.insert(level-1);
      }
    } else {
      println!("{}", self.value);
    }

    if left.is_some() {
      left.unwrap().visualizeTree(level+1, true, columns);
    }
  }

  pub fn printTree(&self) {
    let mut columns = HashSet::new();
    columns.insert(0);
    self.visualizeTree(0, true, &mut columns);
  }
}

आउटपुट कुछ इस तरह है:

┌── 17
      ┌── 3
         └── 9
   └── 2
       └── 1
20
   ┌── 7
         ┌── 16
      └── 15
└── 8
       ┌── 11
    └── 4
        └── 13

0

कंसोल में प्रिंट करें:

                                                500
                       700                                             300   
    200                                   400                                                                                          

सरल कोड:

public int getHeight()
    {
        if(rootNode == null) return -1;
        return getHeight(rootNode);
    }

    private int getHeight(Node node)
    {
        if(node == null) return -1;

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

    public void printBinaryTree(Node rootNode)
    {
        Queue<Node> rootsQueue = new LinkedList<Node>();
        Queue<Node> levelQueue = new LinkedList<Node>();
        levelQueue.add(rootNode);
        int treeHeight = getHeight();
        int firstNodeGap;
        int internalNodeGap;
        int copyinternalNodeGap;
        while(true)
        {
            System.out.println("");
            internalNodeGap = (int)(Math.pow(2, treeHeight + 1) -1);  
            copyinternalNodeGap = internalNodeGap;
            firstNodeGap = internalNodeGap/2;

            boolean levelFirstNode = true;

            while(!levelQueue.isEmpty())
            {
                internalNodeGap = copyinternalNodeGap;
                Node currNode = levelQueue.poll();
                if(currNode != null)
                {
                    if(levelFirstNode)
                    {
                        while(firstNodeGap > 0)
                        {
                            System.out.format("%s", "   ");
                            firstNodeGap--; 
                        }
                        levelFirstNode =false;
                    }
                    else
                    {
                        while(internalNodeGap>0)
                        {
                            internalNodeGap--;
                            System.out.format("%s", "   ");
                        }
                    }
                    System.out.format("%3d",currNode.data);
                    rootsQueue.add(currNode);
                }
            }

            --treeHeight;

            while(!rootsQueue.isEmpty())
            {
                Node currNode = rootsQueue.poll();
                if(currNode != null)
                {
                    levelQueue.add(currNode.left);
                    levelQueue.add(currNode.right);
                }
            }

            if(levelQueue.isEmpty()) break;
        }

    }

0

यहाँ बहुत बहुमुखी पेड़ प्रिंटर है। सबसे अच्छी नहीं लग रही है, लेकिन यह बहुत सारे मामलों को संभालती है। यदि आप यह पता लगा सकते हैं कि स्लैश जोड़ने में संकोच न करें। यहां छवि विवरण दर्ज करें

package com.tomac120.NodePrinter;

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

/**
 * Created by elijah on 6/28/16.
 */
public class NodePrinter{
    final private List<List<PrintableNodePosition>> nodesByRow;
    int maxColumnsLeft = 0;
    int maxColumnsRight = 0;
    int maxTitleLength = 0;
    String sep = " ";
    int depth = 0;

    public NodePrinter(PrintableNode rootNode, int chars_per_node){
        this.setDepth(rootNode,1);
        nodesByRow = new ArrayList<>(depth);
        this.addNode(rootNode._getPrintableNodeInfo(),0,0);
        for (int i = 0;i<chars_per_node;i++){
            //sep += " ";
        }
    }

    private void setDepth(PrintableNode info, int depth){
        if (depth > this.depth){
            this.depth = depth;
        }
        if (info._getLeftChild() != null){
            this.setDepth(info._getLeftChild(),depth+1);
        }
        if (info._getRightChild() != null){
            this.setDepth(info._getRightChild(),depth+1);
        }
    }

    private void addNode(PrintableNodeInfo node, int level, int position){
        if (position < 0 && -position > maxColumnsLeft){
            maxColumnsLeft = -position;
        }
        if (position > 0 && position > maxColumnsRight){
            maxColumnsRight = position;
        }
        if (node.getTitleLength() > maxTitleLength){
           maxTitleLength = node.getTitleLength();
        }
        List<PrintableNodePosition> row = this.getRow(level);
        row.add(new PrintableNodePosition(node, level, position));
        level++;

        int depthToUse = Math.min(depth,6);
        int levelToUse = Math.min(level,6);
        int offset = depthToUse - levelToUse-1;
        offset = (int)(Math.pow(offset,Math.log(depthToUse)*1.4));
        offset = Math.max(offset,3);


        PrintableNodeInfo leftChild = node.getLeftChildInfo();
        PrintableNodeInfo rightChild = node.getRightChildInfo();
        if (leftChild != null){
            this.addNode(leftChild,level,position-offset);
        }
        if (rightChild != null){
            this.addNode(rightChild,level,position+offset);
        }
    }

    private List<PrintableNodePosition> getRow(int row){
        if (row > nodesByRow.size() - 1){
            nodesByRow.add(new LinkedList<>());
        }
        return nodesByRow.get(row);
    }

    public void print(){
        int max_chars = this.maxColumnsLeft+maxColumnsRight+1;
        int level = 0;
        String node_format = "%-"+this.maxTitleLength+"s";
        for (List<PrintableNodePosition> pos_arr : this.nodesByRow){
            String[] chars = this.getCharactersArray(pos_arr,max_chars);
            String line = "";
            int empty_chars = 0;
            for (int i=0;i<chars.length+1;i++){
                String value_i = i < chars.length ? chars[i]:null;
                if (chars.length + 1 == i || value_i != null){
                    if (empty_chars > 0) {
                        System.out.print(String.format("%-" + empty_chars + "s", " "));
                    }
                    if (value_i != null){
                        System.out.print(String.format(node_format,value_i));
                        empty_chars = -1;
                    } else{
                        empty_chars = 0;
                    }
                } else {
                    empty_chars++;
                }
            }
            System.out.print("\n");

            int depthToUse = Math.min(6,depth);
            int line_offset = depthToUse - level;
            line_offset *= 0.5;
            line_offset = Math.max(0,line_offset);

            for (int i=0;i<line_offset;i++){
                System.out.println("");
            }


            level++;
        }
    }

    private String[] getCharactersArray(List<PrintableNodePosition> nodes, int max_chars){
        String[] positions = new String[max_chars+1];
        for (PrintableNodePosition a : nodes){
            int pos_i = maxColumnsLeft + a.column;
            String title_i = a.nodeInfo.getTitleFormatted(this.maxTitleLength);
            positions[pos_i] = title_i;
        }
        return positions;
    }
}

NodeInfo वर्ग

package com.tomac120.NodePrinter;

/**
 * Created by elijah on 6/28/16.
 */
public class PrintableNodeInfo {
    public enum CLI_PRINT_COLOR {
        RESET("\u001B[0m"),
        BLACK("\u001B[30m"),
        RED("\u001B[31m"),
        GREEN("\u001B[32m"),
        YELLOW("\u001B[33m"),
        BLUE("\u001B[34m"),
        PURPLE("\u001B[35m"),
        CYAN("\u001B[36m"),
        WHITE("\u001B[37m");

        final String value;
        CLI_PRINT_COLOR(String value){
            this.value = value;
        }

        @Override
        public String toString() {
            return value;
        }
    }
    private final String title;
    private final PrintableNode leftChild;
    private final PrintableNode rightChild;
    private final CLI_PRINT_COLOR textColor;

    public PrintableNodeInfo(String title, PrintableNode leftChild, PrintableNode rightChild){
        this(title,leftChild,rightChild,CLI_PRINT_COLOR.BLACK);
    }

    public PrintableNodeInfo(String title, PrintableNode leftChild, PrintableNode righthild, CLI_PRINT_COLOR textColor){
        this.title = title;
        this.leftChild = leftChild;
        this.rightChild = righthild;
        this.textColor = textColor;
    }

    public String getTitle(){
        return title;
    }

    public CLI_PRINT_COLOR getTextColor(){
        return textColor;
    }

    public String getTitleFormatted(int max_chars){
        return this.textColor+title+CLI_PRINT_COLOR.RESET;
        /*
        String title = this.title.length() > max_chars ? this.title.substring(0,max_chars+1):this.title;
        boolean left = true;
        while(title.length() < max_chars){
            if (left){
                title = " "+title;
            } else {
                title = title + " ";
            }
        }
        return this.textColor+title+CLI_PRINT_COLOR.RESET;*/
    }

    public int getTitleLength(){
        return title.length();
    }

    public PrintableNodeInfo getLeftChildInfo(){
        if (leftChild == null){
            return null;
        }
        return leftChild._getPrintableNodeInfo();
    }

    public PrintableNodeInfo getRightChildInfo(){
        if (rightChild == null){
            return null;
        }
        return rightChild._getPrintableNodeInfo();
    }
}

NodePosition वर्ग

package com.tomac120.NodePrinter;

/**
 * Created by elijah on 6/28/16.
 */
public class PrintableNodePosition implements Comparable<PrintableNodePosition> {
    public final int row;
    public final int column;
    public final PrintableNodeInfo nodeInfo;
    public PrintableNodePosition(PrintableNodeInfo nodeInfo, int row, int column){
        this.row = row;
        this.column = column;
        this.nodeInfo = nodeInfo;
    }

    @Override
    public int compareTo(PrintableNodePosition o) {
        return Integer.compare(this.column,o.column);
    }
}

और, अंत में, नोड इंटरफ़ेस

package com.tomac120.NodePrinter;

/**
 * Created by elijah on 6/28/16.
 */
public interface PrintableNode {
    PrintableNodeInfo _getPrintableNodeInfo();
    PrintableNode _getLeftChild();
    PrintableNode _getRightChild();
}

0

वासा नोविकोव के उत्तर से अनुकूलित और स्केन बाइनरी पेड़ों के लिए विशेष रूप से तैयार एक स्काला समाधान:

/** An immutable Binary Tree. */
case class BTree[T](value: T, left: Option[BTree[T]], right: Option[BTree[T]]) {

  /* Adapted from: http://stackoverflow.com/a/8948691/643684 */
  def pretty: String = {
    def work(tree: BTree[T], prefix: String, isTail: Boolean): String = {
      val (line, bar) = if (isTail) ("└── ", " ") else ("├── ", "│")

      val curr = s"${prefix}${line}${tree.value}"

      val rights = tree.right match {
        case None    => s"${prefix}${bar}   ├── ∅"
        case Some(r) => work(r, s"${prefix}${bar}   ", false)
      }

      val lefts = tree.left match {
        case None    => s"${prefix}${bar}   └── ∅"
        case Some(l) => work(l, s"${prefix}${bar}   ", true)
      }

      s"${curr}\n${rights}\n${lefts}"

    }

    work(this, "", true)
  }
}

BTW, मैंने एक स्काला समाधान पोस्ट करने का फैसला किया है, वह भी: stackoverflow.com/a/43348945/1091436
VasiliNovikov

0

आप भी देखिए ये जवाब

विशेष रूप से डिफ़ॉल्ट सेटिंग्स के साथ नीचे दिखाए गए परिणाम का उत्पादन करने के लिए अबे ट्रीलेयआउट का उपयोग करना बहुत मुश्किल नहीं था ।

यदि आप उस टूल को आज़माते हैं, तो इस चेतावनी पर ध्यान दें: यह बच्चों को उस क्रम में प्रिंट करता है, जिस क्रम में उन्हें जोड़ा गया था। एक BST के लिए, जहां बाएं बनाम दाएं मामले में मैंने इस लाइब्रेरी को संशोधन के बिना अनुपयुक्त पाया।

इसके अलावा, बच्चों को जोड़ने की विधि बस एक parentऔर childनोड को पैरामीटर के रूप में लेती है । (तो नोड्स के एक समूह को संसाधित करने के लिए, आपको रूट बनाने के लिए पहले एक को अलग से लेना होगा।)

मैंने ऊपर दिए गए इस समाधान का उपयोग करते हुए इसे टाइप में लेने के लिए संशोधित किया है <Node>ताकि Nodeबाएं और दाएं (बच्चों) तक पहुंच हो ।

पेड़ के साथ बनाया


0

यहां आपके पेड़ की कल्पना करने का एक और तरीका है: नोड्स को एक xml फ़ाइल के रूप में सहेजें और फिर अपने ब्राउज़र को आपको पदानुक्रम दिखाने दें:

class treeNode{
    int key;
    treeNode left;
    treeNode right;

    public treeNode(int key){
        this.key = key;
        left = right = null;
    }

    public void printNode(StringBuilder output, String dir){
        output.append("<node key='" + key + "' dir='" + dir + "'>");
        if(left != null)
            left.printNode(output, "l");
        if(right != null)
            right.printNode(output, "r");
        output.append("</node>");
    }
}

class tree{
    private treeNode treeRoot;

    public tree(int key){
        treeRoot = new treeNode(key);
    }

    public void insert(int key){
        insert(treeRoot, key);
    }

    private treeNode insert(treeNode root, int key){
        if(root == null){
            treeNode child = new treeNode(key);
            return child;
        }

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

        return root;
    }

    public void saveTreeAsXml(){
        StringBuilder strOutput = new StringBuilder();
        strOutput.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        treeRoot.printNode(strOutput, "root");
        try {
            PrintWriter writer = new PrintWriter("C:/tree.xml", "UTF-8");
            writer.write(strOutput.toString());
            writer.close();
        }
        catch (FileNotFoundException e){

        }
        catch(UnsupportedEncodingException e){

        }
    }
}

यह परीक्षण करने के लिए कोड है:

    tree t = new tree(1);
    t.insert(10);
    t.insert(5);
    t.insert(4);
    t.insert(20);
    t.insert(40);
    t.insert(30);
    t.insert(80);
    t.insert(60);
    t.insert(50);

    t.saveTreeAsXml();

और आउटपुट इस तरह दिखता है:

यहां छवि विवरण दर्ज करें


0
using map...
{
Map<Integer,String> m = new LinkedHashMap<>();

         tn.printNodeWithLvl(node,l,m);

        for(Entry<Integer, String> map :m.entrySet()) {
            System.out.println(map.getValue());
        }
then....method


   private  void printNodeWithLvl(Node node,int l,Map<Integer,String> m) {
       if(node==null) {
           return;
       }
      if(m.containsKey(l)) {
          m.put(l, new StringBuilder(m.get(l)).append(node.value).toString());
      }else {
          m.put(l, node.value+"");
      }
      l++;
      printNodeWithLvl( node.left,l,m);
      printNodeWithLvl(node.right,l,m);

    }
}

0

यह सबसे सरल संस्करण में से एक है जिसे मैं लागू कर सकता हूं। मुझे उम्मीद है इससे आपको मदद मिली होगी

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

    def add(self, data):

        if data < self.data:
            if self.left is None:
                self.left = Node(data)
            else:
                self.left.add(data)
        if data > self.data:
            if self.right is None:
                self.right = Node(data)
            else:
                self.right.add(data)

    def display(self):
        diff = 16
        start = 50
        c = ' '

        this_level = [(self, start)]

        while this_level:
            next_level = list()
            last_line = ''

            for node, d in this_level:
                line = last_line + c*(d - len(last_line)) + str(node.data)
                print(line, end='\r')
                last_line = line

                if node.left:
                    next_level.append((node.left, d - diff))
                if node.right:
                    next_level.append((node.right, d + diff))
                this_level = next_level
                diff = max(diff//2, 2)
            print('\n')


if __name__ == '__main__':
    from random import randint, choice
    values = [randint(0, 100) for _ in range(10)]
    bst = Node(choice(values))
    for data in values:
        bst.add(data)

    bst.display()

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.