zoukankan      html  css  js  c++  java
  • 利用pygraphviz绘制二叉树

    tree

    用法:

    python treeWriter.py    #输出结果到tree.png
    或者

    python treeWriter.py <output_file_name>


    注意需要安装 graphviz 和 pygraphviz,安装方法见前一篇随笔。

    当前的实现需要用户交互输入二叉树,默认输入-1作为子树空。

    如对应上面的图,可输入

    1 2 7 –1 –1  8 –1 –1 –1  3 4 1 –1  -1 2 –1 9 –1 –1 4 5 3 –1 –1 –1 6 –1 –1

    可以有更好的输入方法,待改进。

    以前写过利用pyqt显示二叉树的随笔,当时用的已经写好的c++实现的二叉树及相应函数,用swig构造一个python可调用的二叉树模块,这里也可以用同样的方法,只要将treeWriter中相应 如 root.left, root.elem改成相应的c++函数转换好的python可调用的二叉树模块中的接口函数名即可。

    而且程序有很好的可扩张性,借助graphviz方便而强大的布局功能,可选的顶点,边参数,用户可以方便的通过继承定义自己的tree writer来绘制不同的二叉树,如下图绘制了一颗建立好的huffman tree.

    >>> l
    ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm']
    >>> w
    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41]

    tree

    来一个复杂一点,我利用绘制的二叉树,来判断压缩过程中生成的huffmantree,以及解压缩过程中写文件后(序列化)之后从文件读出重构的huffmantree是否一致。由于’\n’没有处理好:)暂时不显示key value了,只对比下树形。

    tree1

     

    1.binaryTree.py

    简单定义了二叉链表节点,和二叉树类,给出了通过用户交互输入生成二叉树的方法,及中序遍历方法。

    1 #Notice the differnce of creating tree code with c++, python does not
    2 #support reference the same as c++ not pointer to pointer in python I think
    3 
    4 #Author goldenlock_pku
    5 '''
    6 Ilustrate the create binary tree with user input
    7 inorder travel
    8 '''
    9 class Node():
    10     '''
    11     node will be used in BinaryTree
    12     '''
    13     def __init__(self,elem, left = None, right = None):
    14         self.elem = elem
    15         self.left = left
    16         self.right = right
    17     def __str__(self):
    18         return str(self.elem)
    19 
    20 class BinaryTree():
    21     def __init__(self,root = None):
    22         self.root = root
    23    
    24     def createTree(self, endMark = -1):
    25         '''create a binary tree with user input'''
    26         def createTreeHelp(endMark = -1):
    27             elem = raw_input();
    28             if (elem == str(endMark)):
    29                 return None
    30             root = Node(elem)
    31             root.left = createTreeHelp(endMark)
    32             root.right = createTreeHelp(endMark)
    33             return root       
    34         print('Please input the binary tree data wit ' + str(endMark)\
    35             +' as endmark')       
    36         elem = raw_input()
    37         self.root = Node(elem)
    38         self.root.left = createTreeHelp(endMark)
    39         self.root.right = createTreeHelp(endMark)
    40        
    41     def inorderTravel(self):
    42         def inorderTravelHelp(root):
    43             if not root:
    44                 return 
    45             inorderTravelHelp(root.left)
    46             print(root)
    47             inorderTravelHelp(root.right)       
    48         inorderTravelHelp(self.root)

    2.treeWriter.py

    定义了利用pygraphviz生成dot 文件并进一步生成二叉树图案输出到文件。

    绘制过程采用递归,深度优先遍历,利用了不可见节点和边从而能够始终确保能够分清是左子树还是又子树,如果不采用

    加入不可见节点,边的方法则无法分清,如果绘制树的话可以采用简单的不加不可见节点的方法。

    1 import sys
    2 from binaryTree import *
    3 import pygraphviz as pgv
    4 '''
    5 treeWriter with func wite can write a binary tree to tree.png or user spcified
    6 file
    7 '''
    8 class treeWriter():
    9     def __init__(self, tree):
    10         self.num = 1       #mark each visible node as its key
    11         self.num2 = -1     #makk each invisible node as its key
    12         self.tree = tree
    13        
    14     def write(self, outfile = 'tree.png'):
    15         def writeHelp(root, A):
    16             if not root:
    17                 return
    18            
    19             p = str(self.num)
    20             self.num += 1
    21             A.add_node(p, label = str(root.elem))
    22             q = None
    23             r = None
    24            
    25             if root.left:
    26                 q = writeHelp(root.left, A)
    27                 A.add_node(q, label = str(root.left.elem))
    28                 A.add_edge(p,q)
    29             if root.right:
    30                 r = writeHelp(root.right, A)
    31                 A.add_node(r, label = str(root.right.elem))
    32                 A.add_edge(p,r)
    33                
    34             if q or r:
    35                 if not q:
    36                     q = str(self.num2)
    37                     self.num2 -= 1
    38                     A.add_node(q, style = 'invis')
    39                     A.add_edge(p, q, style = 'invis')
    40                 if not r:
    41                     r = str(self.num2)
    42                     self.num2 -= 1
    43                     A.add_node(r, style = 'invis')
    44                     A.add_edge(p, r, style = 'invis')
    45                 l = str(self.num2)
    46                 self.num2 -= 1
    47                 A.add_node(l, style = 'invis')
    48                 A.add_edge(p, l, style = 'invis')
    49                 B = A.add_subgraph([q, l, r], rank = 'same')
    50                 B.add_edge(q, l, style = 'invis')
    51                 B.add_edge(l, r, style = 'invis')
    52            
    53             return#return key root node
    54                    
    55         self.A = pgv.AGraph(directed=True,strict=True)
    56         writeHelp(self.tree.root, self.A)
    57         self.A.graph_attr['epsilon']='0.001'
    58         print self.A.string() # print dot file to standard output
    59         self.A.layout('dot') # layout with dot
    60         self.A.draw(outfile) # write to file       
    61        
    62  
    63 if __name__ == '__main__':
    64     tree = BinaryTree()
    65     tree.createTree(-1)
    66     tree.inorderTravel()
    67     writer = treeWriter(tree)
    68     if len(sys.argv) > 1:
    69         outfile = sys.argv[1]
    70         writer.write(outfile) #write result to outfile
    71     else:
    72         writer.write() #write result to tree.png
    73    
    74 
  • 相关阅读:
    jQuery tips
    WCF4.0进阶系列—第十一章 编写代码控制配置和通信 (上)
    WCF4.0进阶系列—第九章 事务支持(上)
    WCF4.0进阶系列第二章 寄宿WCF服务
    WCF4.0进阶系列第五章 在因特网环境下保护WCF服务
    [JavaScript] onkeypress and onchange event
    [JavaScript]使用jQuery定制开发自己的UI
    WCF4.0进阶系列第四章 保护企业内部的WCF服务
    WCF4.0进阶系列第六章 维护服务协定和数据协定
    WCF4.0 进阶系列第一章 WCF简介
  • 原文地址:https://www.cnblogs.com/rocketfan/p/1564232.html
Copyright © 2011-2022 走看看