7.15  PROC  CreatAdjList(VAR G:AdjList; V:string; A:ArcList);

        {由各顶点信息V和各条弧的信息A建立有向图的邻接表G}

        {V为字符串,每个顶点由一个字符V[i]表示,共有length(V)}

        {个顶点;A为顺序表,每条弧由其依附的两个顶点(字符)}

        {的序偶<A.pair[j].x,A.pair[j].y>表示,共有A.n条弧。}

  FOR i:=1 TO  length(V) DO  {邻接表初始化,length(V)个顶点}

      [ G[i].vexdata:=V[i];  G[i].firstarc:=NIL  ]

  FOR  i:=1 TO  A.n  DO  {输入A.n条弧}

[  x:=A.pair[i].x ;

y:=A.pair[i].y;  {输入一每条弧依附的两个顶点}

      i:=LOC_VERTEX(G,x);  {判定顶点x在顶点向量中的位序}

      j:=LOC_VERTEX(G,y);  {判定顶点y在顶点向量中的位序}

new(p);

p^.adjvex:=j;

p^.nextarc:=G[i].firstarc;

G[i].firstarc:=p {弧结点插入邻接点链表}

]

 ENDP;


716 PROC InsertVertex(VAR G:Graph;  v:vertex);

       {在采用邻接矩阵存储结构的图G上插入顶点v }

       FOR  i:=1  TO  n  DO  G[i,n+1]:=0;

       FOR  i:=1  TO  n  DO  G[n+1,i]:=0;

       G[n+1,n+1]:=0;  {变为n+1个顶点的邻接矩阵}

PROC InsertArc(VAR G:Graph;  v,w:vertex);

       {在采用邻接矩阵存储结构的图G上插入弧<v,w>}

      i:=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}

      j:=LOC_VERTEX(G,w);  {判定顶点w在顶点向量中的位序}

      G[i,j]:=1;  G[j,i]:=1;

PROC DeleteVertex(VAR G:Graph;  v:vertex);

       {在采用邻接矩阵存储结构的图G上删除顶点v,从n个顶点}

       {变成个n-1顶点,也即从n阶方阵变为n-1阶方阵}

       i:=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}

       {将去掉第i行第i列的n阶方阵变为n-1阶方阵}

       FOR  j:=1  TO  i-1  DO  {左上角}

          FOR k:=1 TO i-1 DO  G1[j,k]:=G[j,k];

       FOR  j:=i+1  TO  n  DO  {左下角}

          FOR k:=1 TO i-1 DO  G1[j-1,k]:=G[j,k];

       FOR  j:= 1  TO i-1  DO  {右上角}

          FOR k:=i+1 TO n  DO  G1[j,k-1]:=G[j,k];

       FOR  j:=i+1  TO  n  DO  {右下角}

          FOR k:= i+1 TO n  DO  G1[j-1,k-1]:=G[j,k];

  PROC DeleteArc(VAR G:Graph;  v,w:vertex);

       {在采用邻接矩阵存储结构的图G上删除弧<v,w>}

      i:=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}

      j:=LOC_VERTEX(G,w);  {判定顶点w在顶点向量中的位序}

G[i,j]:=0;  G[j,i]:=0;

{ 若是有向图只作: G[i,j]:=0 }

ENDP;


717

 PROC InsertVertex(VAR G:AdjList;  v:vertex);

       {在采用邻接表存储结构的图G上插入顶点v }

      G[n+1].vexdata:=v;  G[n+1].firstarc:=NIL 

 ENDP;

PROC InsertArc(VAR G: AdjList;  v,w:vertex);

       {在采用邻接表存储结构的图G上插入弧<v,w>}

      i:=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}

      j:=LOC_VERTEX(G,w);  {判定顶点w在顶点向量中的位序}

new(p); 

p^.adjvex:=j;

p^.nextarc:=G[i].firstarc;

G[i].firstarc:=p {弧结点插入邻接点链表}

      {若是无向图,则应再生成一结点,插入到w的邻接点的链表中}

{   new(p); 

p^.adjvex:=i;

p^.nextarc:=G[j].firstarc;

G[j].firstarc:=p {弧结点插入邻接点链表}

      }

ENDP;

PROC DeleteArc(VAR G: AdjList;  v,w:vertex);

       {在采用邻接表存储结构的有向图G上删除弧<v,w>}

      i:=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}

      j:=LOC_VERTEX(G,w);  {判定顶点w在顶点向量中的位序}

      p:=G[i].firstarc; q:=p;   {qp的前驱}

      IF  p^.adjvex=j

         THEN G[i].firstarc:=p^.nextarc  {wv的第一邻接点}

         ELSE [ WHILE  p^.adjvex<>j  DO

 [  q:=p; p:=p^.nextarc  ]

                q^.nextarc:=p^.nextarc;

              ]

      dispose(p);   

ENDP;


7.17 ()

PROC DeleteVertex(VAR G: AdjList;  v:vertex);

   {在采用邻接表存储结构的图G上删除顶点v,所有与该顶点相关}

   {的弧都应删除,这一向量元素作删除标记。若真删除,得作许多调整}

   i:=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}

   G[i].vexdata:=’#’;  p:=G[i].firstarc; {#’是删除标记}

   WHILE  p<>NIL DO  {将从v发出的弧都删除}

       [  q:=p; p:=p^.nextarc;  dispose(q)  {回收结点空间}  ]

   G[i].firstarc:=NIL

   FOR j:=1 TO n DO  {删除所有以v为弧头{序号为 i}的弧}

     IF i<>j  THEN

       [ p:=G[j].firstarc;

        IF p<>NIL THEN

 IF  p^.adjvex=i

THEN G[j].firstarc:=p^.nextarc

{v是第一邻接点}

              ELSE [found:=false;{v是否是邻接点的标志}

                    WHILE (p<>NIL) AND NOT found DO

                       IF p^.adjvex<>i

THEN [q:=p; p:=p^.nextarc]

                          ELSE [ q^.nextarc:=p^.nextarc;

dispose(p);

found:=true

                                ]

       ]   {END OF  FOR j:=1 TO n  DO}

ENDP;

 


718 PROC DeleteVertex(VAR G: OrthoList;  v:vertex);

    {在采用十字链表存储结构的图G上删除顶点v,所有与该顶点相}

    {关的弧都应删除,这一向量元素作删除标记。若真删除,得作许}

     {多调整。}

     i:=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}

G[i].data:=’#’; G[i].firstin:=G[I].firstout:=NIL;

 {删除顶点,作标记}

     FOR j:=1 TO n  DO { 删除以顶点v为弧头的弧}

        IF  j<>i THEN

          [ p:=G[j].firstout;  {先查看第一邻接点是否是v}

           IF p^.headvex=v

 THEN G[j].firstout:=p^.firstout

             ELSE [q:=p; found:=false; {查以v为弧头的顶点}

                   WHILE (p<>NIL) AND NOT found DO

                      IF p^.headvex=v

                         THEN [q^.tlink:=p^.tlink;found:=true]

                         ELSE [q:=p; p:=p^.tlink]

                   ]

           ]

       FOR j:=1 TO n  DO { 删除以顶点v为弧尾的弧}

        IF  j<>i THEN

          [ p:=G[j].firstin; {先查看第一邻接点是否是v}

           IF p^.tailvex=v

 THEN G[j].firstin:=p^.firstin

ELSE

[q:=p; found:=false; {查以v为弧尾头的顶点}

                 WHILE (p<>NIL) AND NOT found DO

                    IF p^.tailvex=v

                      THEN [ q^.hlink:=p^.hlink; found:=true; ]

                      ELSE [ q:=p; p:=p^.hlink]

                 ]

          ] {END OF  FOR j:=1 TO n  DO}

 ENDP;

 

 

 

7.18 ()

PROC InsertVertex(VAR G:OrthoList;  v:vertex);

       {在采用十字链表存储结构的图G上插入顶点v }

      G[n+1].data:=v;  G[n+1].firstin:=NIL; G[n+1].firstout:=NIL; 

PROC InsertArc(VAR G: OrthoList;  v,w:vertex);

       {在采用十字链表存储结构的图G上插入弧<v,w>}

      i=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}

      j:=LOC_VERTEX(G,w);  {判定顶点w在顶点向量中的位序}

new(p);

p^.headvex:=i;  p^.tailvex:=j;

p^.tlink:=G[i].firstout; 

G[i].firstout:=p {弧结点插入i的邻接点链表}

      p^.hlink:=G[j].firstin;  G[j].firstin:=p {插入以j为弧头的链表}

PROC DeleteArc(VAR G: OrthoList;  v,w:vertex);

       {在采用十字链表存储结构的有向图G上删除弧<v,w>}

      i:=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}

      j:=LOC_VERTEX(G,w);  {判定顶点w在顶点向量中的位序}

      p:=G[i].firstout;  {先查看第一邻接点是否是w}

      IF p^.headvex=w THEN G[i].firstout:=p^.firstout

         ELSE [q:=p; found:=false;

               WHILE (p<>NIL) AND NOT found DO

                       IF p^.headvex=w

                          THEN [q^.tlink:=p^.tlink;found:=true]

                          ELSE [q:=p; p:=p^.tlink]

              ]

      p:=G[j].firstin; {先查看第一邻接点是否是v}

      IF p^.tailvex=v THEN G[j].firstin:=p^.firstin

        ELSE [q:=p; found:=false;

              WHILE (p<>NIL) AND NOT found DO

                IF p^.tailvex=v 

THEN [q^.hlink:=p^.hlink; found:=true; ]

                    ELSE [q:=p; p:=p^.hlink]

ENDP;


7.19718 PROC DeleteVertex(VAR G: OrthoList;  v:vertex);

    {在采用十字链表存储结构的图G上删除顶点v,所有与该顶点相}

    {关的弧都应删除,这一向量元素作删除标记。若真删除,得作许}

     {多调整。}

     i:=LOC_VERTEX(G,v);  {判定顶点v在顶点向量中的位序}


7.22 PROC  Connect_DFS(VAR g:adjlisttp,i,j:vtxptr)

      {基于图的深度优先策略,本算法判断以邻接表为存储结构的有}

{向图g中,是否存在顶点i到顶点j的路径。i<=i,j<=n,i<>j  }

     PROC dfs(g:adjlist;i,j:vtxptr);

      {g用邻接表存储。本算法从顶点 i 出发,深度优先遍历,}

{若遍历到j结点,则说明顶点ij有通路。}

      visited[i]:=true;   

      IF i=j

THEN  found:=true  { ij有通路}

        ELSE [ p:=g[i].firstarc;

               WHILE p<>NIL DO

                  [ k:=p^.adjvex;

                   IF NOT  visited[k]  THEN dfs(g,k,j);

                   IF  NOT  found  THEN  p:=p^.nextarc

                  ]

     ENDP;  {END OF PROC dfs }

{调用dfs的主过程如下:}

  [ visited[1..n]:=false; found:=false;{标志,全程变量}

    readln(i,j); {读入顶点(i,j)}       dfs(g,i,j);

    IF found THEN writeln(‘顶点’ , i , ’ ‘ ,j,’ 有通路’)

            ELSE writeln(‘顶点 ‘ ,i,’ ‘,j,’ 没有通路’)

  ]     {END OF PROC OF path_i_to_j  }

ENDP;

723   PROC bfs(g:adjlist; i,j:vtxptr);

      {算法说明同上,这里是宽度优先遍历}

  INITQUEUE(q);  ENQUEUE(q,i);

WHILE (NOT EMPTY(q)) AND (NOT found ) DO

[i:=DELQUEUE(q);  visited[i]:=true;   

    IF i=j THEN  found:=true

       ELSE [ p:=g[i].firstarc;

             WHILE p<>NIL DO

                [ w:=p^.adjvex;

                 IF NOT  visited[w]  THEN ENQUEUE(q,w);

                  p:=p^.nextarc

                ]

     ENDP;  {END OF PROC dfs }

 

 

7.38  PROC InversePolish(G:Adjlist; v:vtxptr; VAR ip:String);

      {有向无环图G用邻接表存储,四则运算算术表达式用G表示。}

{假设表达式中操作数都是单字母变量。本算法求该表达式的逆}

{波兰表达式。假定v是有向无环图的入度为0的顶点。}

P:=G[v].firstarc;

WHILE p<>NIL DO

   [ w:=p^.adjvex;  InversePolish(G,w,ip);

    p:=p^.nextarc;

   ]

ip:=ip+G[v].vexdata;   {逆波兰表达式存在ip 字符串中}

ENDP


7.38

{以下是非递归算法}

PUSHs,v;

WHILE  NOT  EMPTY(s)  DO

   [j:=POP(s);

p:=G[I].firstarc;

WHILE  p<>NIL  DO

   [  w:=p^.adjvex; {邻接点}

PUSH(s,w);

P:=G[w].firstarc;  {w的第一邻接点}

        ]

 w:=POP(s);  ip:=ip+G[w].vexdata;

p:=p^.nextarc

      ]