0

I have developed a binary search tree structure and I want to add some function which can visualize the tree. The code below belongs to Binary Search Tree:

class Node(object):
    def __init__(self, data):
        self.data = data
        self.leftChild = None
        self.rightChild = None

    def insert(self, data):
        if data < self.data:
            if not self.leftChild:
                self.leftChild = Node(data)
                return True
            else:
                self.leftChild.insert(data)
        else:
            if not self.rightChild:
               self.rightChild = Node(data)
               return True
            else:
               self.rightChild.insert(data)
    def inOrder(self):
        """
        Traversing the tree in inorder form (LVR).

        """
        if self:
            if self.leftChild:
               self.leftChild.inOrder()
            print(self.data)
            if self.rightChild:
                self.rightChild.inOrder()
class BST(object):
    def __init__(self):
        self.rootNode = None

    def insert(self, data):
        if not self.rootNode:
            self.rootNode = Node(data)
        else:
            self.rootNode.insert(data)
    def inOrder(self):
        self.rootNode.inOrder()

you can test the code to see how it traverses the tree recursively:

bst = BST()

bst.insert(12)
bst.insert(14)
bst.insert(8)
bst.insert(11)
bst.insert(7)
bst.inOrder()

For the visualization, I have used ete library. In ete3 library if you use the code below:

from ete3 import Tree
# Loads a tree. Note that we use format 1 to read internal node names
tree_format = '(((J)H,K)D,((S,E)A,(T)B)C)F;'
t = Tree(tree_format, format=1)
print( t.get_ascii())

you will get an output like this:

      /H /-J
   /D|
  |   \-K
-F|
  |      /-S
  |   /A|
   \C|   \-E
     |
      \B /-T

As you can see in the code above if I could be able to create the variable tree_format out of the BST structure, then I would be able to have a visual representation of tree.
To do this,the program has to
1. Traverse the tree in RLV format.
2. during traversing, it has to use () , , and ;.
Can anyone help me to complete the code.
If anyone has any easier way for visualizing the BST, I would be really grateful to see.
Thank you guys.

Masoud Masoumi Moghadam
  • 1,094
  • 3
  • 23
  • 45
  • Seems like if you do a reverse post-order traversal, keeping track of depth, you've got it. When depth increases, you add a left paren. You add a comma between nodes at the same depth, and when depth decreases you add a right paren. – Jim Mischel Sep 22 '16 at 17:43
  • It seems that if I use non-recursive mode for traversal, I might get a clue to solve the problem – Masoud Masoumi Moghadam Sep 22 '16 at 22:15

3 Answers3

2

I think a recursive traversal will be easiest. With a non-recursive solution you end up having to manage the stack yourself.

Here's some code in C#, which you should be able to port to Python easily enough:

string Traverse(Node node)
{
    string rslt = "";
    bool hasRightNode = false;
    bool hasLeftNode = false;
    if (node.Right != null)
    {
        hasRightNode = true;
        rslt = rslt + "(";
        rslt = rslt + Traverse(node.Right);
    }
    if (node.Left != null)
    {
        hasLeftNode = true;
        if (hasRightNode)
        {
            rslt = rslt + ",";
        }
        else
        {
            rslt = rslt + "(";
        }
        rslt = rslt + Traverse(node.Left);
    }
    if (hasLeftNode || hasRightNode)
    {
        rslt = rslt + ")";
    }
    rslt = rslt + node.Value;
    return rslt;
}

The only thing missing is the final semicolon. You can call it with:

string format = Traverse(root) + ";";

Given the tree that you posted, that outputs the expected format string.

Note that I use string concatenation here, which is sub-optimal in C#. If this were a production program, I'd probably use a StringBuilder object to avoid concatenation. I'm not familiar enough with Python to say how best to compose strings in that language.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
0

According to Mr.Jim Mischel sample code in C#, I added the following function in the Node class:

def R_postorder(self):
    ret = ''
    if self:
        hasRightChild = False
        hasLeftChild = False
        if self.rightChild:
            hasRightChild = True
            ret += '('
            ret += self.rightChild.RLV()

        if self.leftChild:
            hasLeftChild = True
            if hasRightChild:
                ret += ','
            else:
                ret += '('
            ret += self.leftChild.RLV()
        if hasRightChild or hasLeftChild:
            ret += ')'
        ret += str(self.data)
    return ret

and I also added the R_postorder to the BST class:

def R_postorder(self):
    ret = self.rootNode.RLV()
    ret += ';'
    return ret

By using the returned value of bst.R_postorder() as an input to create the tree_format variable, the right outcome would be achieved.

Masoud Masoumi Moghadam
  • 1,094
  • 3
  • 23
  • 45
  • It's not very friendly, asking for help and then not giving full credit to the person who provides you the answer. Marking your own post as the accepted answer deprives the person who actually solved your problem from getting the points for it. I personally don't really care about a few points, because I have plenty, but others do, and you could find that people are unwilling to help you. – Jim Mischel Oct 01 '16 at 12:58
  • I'm sorry my friend. I didn't mean like that.I thought that the right answer is the one which is answered using python not C#. that's why I didn't mark your code. You should know this was a misunderstanding and nothing intentional. Because as you see I appreciated your help and also mentioned your name in my answer. please don't mind it. I'm not professional yet as much as you are – Masoud Masoumi Moghadam Oct 02 '16 at 16:51
  • 1
    Not a problem. Just a friendly reminder. Welcome to Stack Overflow. – Jim Mischel Oct 02 '16 at 17:17
0
  1. You will need to level order traverse your tree.
  2. Choose node length and space length.
  3. Get the tree's base width relative to each level which is node_length * nodes_count + space_length * spaces_count*.
  4. Find a relation between branching, spacing, indentation and the calculated base width.

Code on GitHub: YoussefRaafatNasry/bst-ascii-visualization

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