使用graphviz绘制双向链表
Posted
技术标签:
【中文标题】使用graphviz绘制双向链表【英文标题】:Draw doubly linked list using graphviz 【发布时间】:2022-01-23 05:58:36 【问题描述】:我使用 Graphviz(点)绘制了一个双向链表,如下所示,但节点未对齐。如何对齐节点?
digraph "Doubly Linked List"
rankdir=LR;
node [shape=record];
e [label="nil" shape=circle];
a [label=" <ref1> | <data> 1 | <ref2> "]
b [label=" <ref1> | <data> 5 | <ref2> "];
c [label=" <ref1> | <data> 7 | <ref2> "];
d [label="nil" shape=circle];
e -> a:ref1:c [arrowhead=dot, arrowtail=vee, dir=both, headclip=false];
a:ref2:c -> b:data:n [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
b:ref2:c -> c:data:n [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
c:ref2:c -> d [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
c:ref1:c -> b:data:s [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
b:ref1:c -> a:data:s [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
【问题讨论】:
【参考方案1】:Sroush提供了类似html形状的解决方案,但我找到了一种使用记录节点here的方法,如下:
digraph "Doubly Linked List"
rankdir=LR;
node [shape=record];
e [label="nil" shape=circle];
a [label=" <ref1> | <data> 1 | <ref2> "]
b [label=" <ref1> | <data> 5 | <ref2> "];
c [label=" <ref1> | <data> 7 | <ref2> "];
d [label="nil" shape=circle];
e -> a:ref1:c [arrowhead=dot, arrowtail=vee, dir=both, headclip=false];
a:ref2:c -> b:data:n [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
b:ref2:c -> c:data:n [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
c:ref2:c -> d [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
c:ref1:c -> b:data:s [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
c:ref1:c -> b:data:w[weight = 100, style = invis]; <- add this
b:ref1:c -> a:data:s [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
b:ref1:c -> a:data:w[weight = 100, style = invis]; <- add this
【讨论】:
【参考方案2】:在高层次上,答案是rank=same ... nodes here ...
但是,记录形状的节点和排名相同的边缘会产生点烧心,或者更准确地说会产生以下错误消息:
Warning: flat edge between adjacent nodes one of which has a record shape - replace records with HTML-like labels
Edge e -> a
Error: lost e a edge
Error: lost a b edge
Error: lost b a edge
Error: lost b c edge
Error: lost c b edge
Error: lost c d edge
因此,如果我们将节点更改为“类似 html”的形状 (https://graphviz.org/doc/info/shapes.html#href),您会得到:
digraph "Doubly Linked List"
node [shape=plaintext] // for correct display of table
rank=same // all on same rank
e [label="nil" shape=circle];
a [label=<<table border="0" cellspacing="0" cellborder="1"><tr>
<td port="ref1" fixedsize="true"></td>
<td port="data" fixedsize="true">1</td>
<td port="ref2" fixedsize="true"></td>
</tr></table>>]
b [label=<<table border="0" cellspacing="0" cellborder="1"><tr>
<td port="ref1" fixedsize="true"></td>
<td port="data" fixedsize="true">5</td>
<td port="ref2" fixedsize="true"></td></tr>
</table>>]
c [label=<<table border="0" cellspacing="0" cellborder="1"><tr>
<td port="ref1" fixedsize="true"></td>
<td port="data" fixedsize="true">7</td>
<td port="ref2" fixedsize="true"></td>
</tr></table>>]
d [label="nil" shape=circle];
e -> a:ref1:c [arrowhead=dot, arrowtail=vee, dir=both, headclip=false];
a:ref2:c -> b:data:n [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
b:ref2:c -> c:data:n [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
// added :w to straighten edge
c:ref2:c -> d:w [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
c:ref1:c -> b:data:s [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
b:ref1:c -> a:data:s [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false];
(对不起),但它会给你:
【讨论】:
以上是关于使用graphviz绘制双向链表的主要内容,如果未能解决你的问题,请参考以下文章