简体   繁体   中英

How to draw linked-list in graphviz without cross the node?

I've defined a list_t structure and a list_node_t structure as follows:

typedef struct taglist_node_t {
    struct taglist_node_t  *pstNext;
    void                   *pData;
} list_node_t;

typedef struct taglist_t {
    list_node_t     stHead;
    list_node_t    *pstTail;
    unsigned int    uiCount;
} list_t;

And I decide to draw the above linked-list using graphviz, and the code as here:

digraph g {
    bgcolor="#BBCAF2";
    label="\nSingle Linked List\n";

    graph[rankdir=LR, center=true, margin=0.2, nodesep=1, ranksep=1]
    edge[arrowsize=1.0, arrowhead=vee]
    node[shape = Mrecord, fontname="Consolas", fontsize=20, width=1, height=1, fixedsize=false];

    list[label = "<name> slist_t | <head> stHead | <tail> *pstTail | uiCount"];
    node0[label = "<name> list_node_t | <next> *pstNext | *pData"];
    node1[label = "<name> list_node_t | <next> *pstNext | *pData"];
    head[label = "pstList"];

    head -> list:name[style=bold, color=red, dir=both, arrowtail=dot];
    list:head:e -> node0:name[dir=forward, arrowtail=normal];
    list:tail:e -> node1:name[dir=both, arrowtail=dot];
    node0:next:e -> list:head:w[dir=both, arrowtail=dot];
    node1:next:e -> list:head:w[dir=both, arrowtail=dot, color=blue];
}

But as you can see from the following result, the blue line cross the other nodes. And my question is how to avoid this or move the blue line below the node1 in order to avoid edge crossing?

The GraphViz result:

GraphViz .dot输出

Basically there is no solution for this problem. you can play with the parameters to optimize a concrete layout but not in general.

increasing weight for the blue edge gives the most acceptable layout.

digraph g {
    bgcolor="#BBCAF2";
    label="\nSingle Linked List\n";

    graph[rankdir=LR, center=true, margin=0.2, nodesep=1, ranksep=1]
    edge[arrowsize=1.0, arrowhead=vee]
    node[shape = Mrecord, fontname="Consolas", fontsize=20, width=1, height=1, fixedsize=false];

    list[label = "<name> slist_t | <head> stHead | <tail> *pstTail | uiCount"];
    node0[label = "<name> list_node_t | <next> *pstNext | *pData"];
    node1[label = "<name> list_node_t | <next> *pstNext | *pData"];
    head[label = "pstList"];

    head -> list:name[style=bold, color=red, dir=both, arrowtail=dot];
    list:head:e -> node0:name[dir=forward, arrowtail=normal];
    list:tail:e -> node1:name[dir=both, arrowtail=dot];
    node0:next:e -> list:head:w[dir=both, arrowtail=dot];
    node1:next:e -> list:head:w[dir=both, arrowtail=dot, color=blue, weight=10];
}

But node0 should not have an edge to list anyway, most probable it should point to node1 . And node1 should not point anywhere.

Finally to your C implementation - stHead shall be a pointer as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM