需要帮助创建拓扑排序图

需要帮助创建拓扑排序图

有人知道我如何在 LaTeX 中创建类似以下“拓扑排序”的图表吗?它也可以是水平的,不必是垂直的。

提前致谢。拓扑排序

答案1

使用Asymptote面向对象的方法,类定义(文件gsort.asy):

struct gSortSkin{
    real dx,dNode,dlink;
    guide contour;
    pen nodePen,nodeBgPen,labelPen,linkPen;
    arrowbar arr;
    string TeXlabelMacro="";

    void operator init(real dx, real dNode, real dlink, 
    guide contour,
    pen nodePen=currentpen,
    pen nodeBgPen=nullpen,
    pen labelPen=currentpen,
    pen linkPen=currentpen,
    arrowbar arr=Arrow,
    string TeXlabelMacro=""
    ){
        this.dx=dx; this.dNode=dNode; this.dlink=dlink; 
        this.contour=contour; 
        this.nodePen  =nodePen  ;
        this.nodeBgPen=nodeBgPen;
        this.labelPen =labelPen ;
        this.linkPen  =linkPen  ;
        this.arr=arr;  
        this.TeXlabelMacro=TeXlabelMacro; 
    }
}

gSortSkin colorSkin1=gSortSkin(
dx=0,dNode=18mm,dlink=16mm,
contour=circle((0,0),6mm),
nodePen=deepblue+0.5bp,
nodeBgPen=lightyellow,
labelPen=brown,
linkPen=orange+0.5bp,
arr=Arrow(HookHead,size=0.5,angle=60),
TeXlabelMacro=""
);

gSortSkin BWSkin=gSortSkin(
dx=0,dNode=18mm,dlink=16mm,
contour=circle((0,0),6mm),
nodePen=black+0.5bp,
nodeBgPen=white,
labelPen=black,
linkPen=black+0.5bp,
arr=Arrow(HookHead,size=0.5,angle=60),
TeXlabelMacro=""
);



struct gSort{
    picture pic;
    int n;
    int[] list;
    int[][][] aLinks;
    bool vertical;
    gSortSkin skin;
    pair[] elPos;
    transform tr;

    void drawLinks(){
        guide glink;

        for(int i=0;i<aLinks.length;++i){
            for(int j=0;j<aLinks[i].length;++j){        
                if(aLinks[i][j][1]>0){
                    glink=elPos[i]..((elPos[i]+elPos[i+aLinks[i][j][1]])/2+skin.dlink*aLinks[i][j][0])..elPos[i+aLinks[i][j][1]];
                    glink=cut(glink,shift(elPos[i])*skin.contour,1).after;
                    glink=cut(glink,shift(elPos[i+aLinks[i][j][1]])*skin.contour,1).before;
                    draw(pic,tr*glink,skin.linkPen,skin.arr);
                }
            }
        }
    }

    void draw(){
        pair v;
        for(int i=0;i<n;++i){
            v=(0,-i*skin.dNode);
            elPos[i]=v;
            filldraw(pic, tr*shift(v)*skin.contour,skin.nodeBgPen,skin.nodePen);
        }
        for(int i=0;i<n;++i){
            v=(0,-i*skin.dNode);
            label(pic,"$"+skin.TeXlabelMacro+"{"+string(list[i])+"}$",tr*v,skin.labelPen);
        }
        drawLinks();
    }

    void operator init(picture pic=currentpicture, 
    int[] list, 
    int[][][] aLinks,
    bool vertical=true,
    gSortSkin skin=colorSkin1
    ){
        this.pic=pic;
        this.list=list;
        this.n=list.length;
        this.aLinks=aLinks;
        this.elPos=new pair[];
        this.skin=skin;
        this.vertical=vertical;
        if(vertical){
            tr=identity();
        }else tr=rotate(90); 
    }
}

使用示例:

// gsorttest.asy
//
// run 
// asy gsorttest.asy
// to get gsorttest.pdf
//
settings.tex="pdflatex";
import gsort;
size(10cm); import fontsize;defaultpen(fontsize(9pt));
texpreamble("\usepackage{lmodern}");

int[] nodeList={8,7,2,3,0,6,9,10,11,12,1,5,4};
int[][][] aLinks={ // for every node: {{left=-1,-2,;mid=0;right=1,2,}, 
                   //             {relative link to node from current node| 0, if no link}}
    {{ 0,+1}},
    {{-2,+4}},
    {{-1,+2},{0,+1}},
    {{+3,+8}},
    {{ 0,+1},{+1,+6},{+2,+7}},
    {{-3,+7},{0,+1}},
    {{-1,+2},{-2,+3},{ 0,+1}},
    {{ 0,0}},
    {{ 0,+1}},
    {{ 0,0}},
    {{ 0,0}},
    {{ 0,+1}},
    {{ 0,0}},
};

gSortSkin skin=colorSkin1;
skin.TeXlabelMacro="\mathtt";
skin.nodeBgPen=palegreen;
skin.nodePen=skin.nodePen+1.5bp;
skin.linkPen=lightblue;

gSort gs=gSort(nodeList,aLinks,vertical=false,skin=skin);

gs.draw();

在此处输入图片描述

答案2

简短的代码如下pstricks

\documentclass[svgnames]{article}
\usepackage{pst-node, auto-pst-pdf}%% auto-pst-pdf to compile with pdflatex
\begin{document}

\begin{pspicture}
\foreach\value[count=\y] in {4,5,1,12,11,10,9,6,0,3,2,7,8}{\Cnodeput[radius=2.8mm](0,\y){\value}{\value}}
\rput(0,14){\Rnode{D}{\textcolor{IndianRed}{\itshape point down}}}
\psset{linewidth=0.6pt, linecolor=SteelBlue, arrows =-> ,arrowinset=0.12}
\foreach\be/\en in {8/7,2/3,0/6,6/9,9/10,11/12,5/4}{\ncline{\be}{\en}}
\ncline{D}{8}
\foreach\be/\en in {7/6,2/0,6/4,9/12}{\nccurve[angleA=-135, angleB=135]{\be}{\en}}
\nccurve[angleA=-125, angleB=125]{9}{11}
\nccurve[angleA=-40, angleB=40]{3}{5}
\nccurve[angleA=-35, angleB=60]{0}{5}
\nccurve[angleA=-50, angleB=60]{0}{1}
\end{pspicture}

\end{document} 

在此处输入图片描述

关于代码的一些解释:

我首先扫描要显示的值列表,并将每一项(\valuecircle node放在轴,纵坐标为列表中的顺序号(count=\y),名称为插入的值,并将小红色文本作为名为的矩形节点放在顶部D

然后我设置一些参数(线宽、线颜色等)。最后,节点通过直线(\ncline)或贝塞尔曲线( )连接。对于这些曲线,我必须在开始(参数)和结束( )\nccurve时指定相对于水平线的角度,这样曲线才不会混乱。angleA\angleB

答案3

我认为我做对了。请给我意见或建议:)

\documentclass{minimal}
\usepackage{tikz}
\usepackage{verbatim}
\usepackage{forest}
\usetikzlibrary{arrows,trees,positioning}
\tikzstyle{circleobject}=[circle,fill=white,draw,line width=0.5mm]
\tikzstyle{line}=[draw]
\tikzstyle{arrow}=[draw, -latex]

\begin{comment}
\end{comment}

\tikzset{%
    /forest,
    forest node/.style={circle, inner sep=0pt, text centered},
    arn n/.append style={text=white, font=\sffamily\bfseries, draw=black, text width=1.5em},
    arn r/.append style={text=red, draw=red, text width=1.5em, very thick},
  }
\begin{document}
  \begin{tikzpicture}
  \draw (0,0) node[circleobject] (Small2A) {3};
  \draw (1.5,0) node[circleobject] (Small2B) {7};
  \draw (3,0) node[circleobject] (Small2C) {1};
  \draw (4.5,0) node[circleobject] (Small2D) {0};
  \draw (6,0) node[circleobject] (Small2E) {5};
  \draw (7.5,0) node[circleobject] (Small2F) {2};
  \draw (9,0) node[circleobject] (Small2G) {6};
  \draw (10.5,0) node[circleobject] (Small2H) {4};
  \draw (12,0) node[circleobject] (Small2I) {8};
  \draw (13.5,0) node[circleobject] (Small2J) {9};
  %%
  \draw[-latex,bend left]  (Small2A) edge (Small2B);
  \draw[-latex,bend right]  (Small2A) edge (Small2I);
  \draw[-latex,bend left]  (Small2B) edge (Small2I);

\end{tikzpicture}
\end{document}

拓扑排序

相关内容