有没有办法让二叉搜索树的简单ascii可视化?

时间:2016-09-21 20:41:33

标签: algorithm python-3.x binary-search-tree ete3

我开发了二叉搜索树结构,我想添加一些可以显示树的功能。 以下代码属于二进制搜索树:

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()

您可以测试代码以查看它如何递归遍历树:

bst = BST()

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

对于可视化,我使用了ete库。 如果您使用以下代码,请在ete3库中:

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())

你会得到这样的输出:

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

正如您在上面的代码中所看到的,如果我能够从BST结构中创建变量tree_format,那么我将能够以树的可视化表示。
要做到这一点,程序必须具有 1.以RLV格式遍历树 2.在遍历期间,必须使用(),; 任何人都可以帮我完成代码。
如果有人有更容易的方式来形象化BST,我将非常感激 谢谢你们。

3 个答案:

答案 0 :(得分:1)

我认为递归遍历最简单。使用非递归解决方案,您最终必须自己管理堆栈。

这是C#中的一些代码,你应该能够轻松地移植到Python:

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;
}

唯一缺少的是最后一个分号。您可以使用以下方式调用它:

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

根据您发布的树,输出预期的格式字符串。

请注意,我在这里使用字符串连接,这在C#中是次优的。如果这是一个生产程序,我可能会使用StringBuilder对象来避免连接。我对Python不太熟悉,不知道如何最好地用这种语言编写字符串。

答案 1 :(得分:0)

根据C#中的Mr.Jim Mischel示例代码,我在Node类中添加了以下函数:

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

我还将R_postorder添加到BST类:

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

通过使用bst.R_postorder()的返回值作为创建tree_format变量的输入,可以实现正确的结果。

答案 2 :(得分:0)

  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