使用graphviz绘制二叉树(二)

网友投稿 635 2022-11-12

使用graphviz绘制二叉树(二)

使用graphviz绘制二叉树(二)

在上一篇博客中《​​使用graphviz绘制二叉树​​​》,提到了一些graphviz的简单的用法。可是如果用上一篇文章中介绍的方法绘制二叉树的话,画出来是及其丑陋的,子节点位置摆放不太好看。自己可以动手试试! 比如我编写了一个tree.dot文件:

graph g { graph[ordering="out"]; A--B; A--C; B--D; B--E; C--F; C--NULL[style="invis"]; A[shape="circle"]; B[shape="circle"]; C[shape="circle"]; D[shape="circle"]; E[shape="circle"]; F[shape="circle"]; NULL[style="invis"];}

输出结果是这样的:

有没有丑出新境界???

于是,我就进行了Google,发现了Github上还有有人做了相关工作的 ​​GraphViz formatting script for binary trees​​​。 -上面链接中的代码文件,然后对自己的原始dot文件执行如下命令: (假设-的代码文件名称为binarytree.gvpr,自己的dot文件名称为tree.dot,输出文件为tree.png)

dot tree.dot | gvpr -c -f binarytree.gvpr | neato -n -Tpng -o tree.png

我们再来看看运行的结果:

现在是不是好看多了!

gvpr是一种叫做graph pattern scanning and processing language的语言,有兴趣的童鞋可以自己Google,我自己是一句都看不懂。 为了方便起见,我把binarytree.gvpr文件的源码贴出来。

// from Emden Gansner// requires GraphViz 2.28.0 (fails with 2.26.3 at least)BEGIN { double tw[node_t]; // width of tree rooted at node double nw[node_t]; // width of node double xoff[node_t]; // x offset of root from left side of its tree double sp = 36; // extra space between left and right subtrees double wd, w, w1, w2; double x, y, z; edge_t e1, e2; node_t n;}BEG_G { $.bb = ""; $tvtype=TV_postfwd; // visit root after all children visited}N { sscanf ($.width, "%f", &w); w *= 72; // convert inches to points nw[$] = w; if ($.outdegree == 0) { tw[$] = w; xoff[$] = w/2.0; } else if ($.outdegree == 1) { e1 = fstout($); w1 = tw[e1.head]; tw[$] = w1 + (sp+w)/2.0; if (e1.side == "left") xoff[$] = tw[$] - w/2.0; else xoff[$] = w/2.0; } else { e1 = fstout($); w1 = tw[e1.head]; e2 = nxtout(e1); w2 = tw[e2.head]; wd = w1 + w2 + sp; if (w > wd) wd = w; tw[$] = wd; xoff[$] = w1 + sp/2.0; }}BEG_G { $tvtype=TV_fwd; // visit root first, then children}N { if ($.indegree == 0) { sscanf ($.pos, "%f,%f", &x, &y); $.pos = sprintf("0,%f", y); } if ($.outdegree == 0) return; sscanf ($.pos, "%f,%f", &x, &y); wd = tw[$]; e1 = fstout($); n = e1.head; sscanf (n.pos, "%f,%f", &z, &y); if ($.outdegree == 1) { if (e1.side == "left") n.pos = sprintf("%f,%f", x - tw[n] - sp/2.0 + xoff[n], y); else n.pos = sprintf("%f,%f", x + sp/2.0 + xoff[n], y); } else { n.pos = sprintf("%f,%f", x - tw[n] - sp/2.0 + xoff[n], y); e2 = nxtout(e1); n = e2.head; sscanf (n.pos, "%f,%f", &z, &y); n.pos = sprintf("%f,%f", x + sp/2.0 + xoff[n], y); }}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:当攀藤 PM2.5 传感器遇上 RT-Thread
下一篇:Tracking Analyst Tools(Tracking Analyst 工具)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~