通过graphviz绘制二叉树,提供demo
通过graphviz绘制二叉树,提供demo
本文将演示绘制如图所示的二叉树过程:
-
ubuntu安装graphviz:
sudo apt install graphviz
-
新建一个
binarytree.gvpr
文件,该文件用于美化二叉树显示,不需要修改。(或者点击这里下载)
binarytree.gvpr
文件:// from Emden Gansner // https://mailman.research.att.com/pipermail/graphviz-interest/2010q2/007101.html // 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); } }
-
新建.dot文件,该文件用于绘制二叉树,按照二叉树的结构绘制
tree.dot
:digraph binaryTree{ // 设置结点形状,颜色,字体颜色和大小 node[shape=circle,color=black,fontcolor=black,fontsize=10]; // draw edge // 注意:若树只有一个节点,该节点会向右对齐,显示为右孩子 // 若树有两个节点,第一个节点显示为左孩子,第二个节点显示为右孩子。 // 为了不混淆,建议树的左右孩子多添加,根据需要隐藏边和节点即可。 //A[color=blue,fontcolor=black,fontsize=20]; //root->a[style=dotted]; A->B;//绘制一条从A结点到B节点的边,并绘制A结点和B结点 A->C; B->D; B->D2[style=invis];//hide edge C->E; C->F; D->G; D->H; E->I; // hide node // 注意:要先画边再隐藏节点。否则左右孩子显示错误 D2[style=invis];//hide edge }
-
将
tree.dot
和binarytree.gvpr
放到同一目录下,在该目录下执行命令行:dot tree.dot | gvpr -c -f binarytree.gvpr | neato -n -Tpng -o tree.png
这将会在当前目录下生成tree.png: