第8章 图习题与解析.docx

上传人:b****6 文档编号:8681192 上传时间:2023-02-01 格式:DOCX 页数:33 大小:25.71KB
下载 相关 举报
第8章 图习题与解析.docx_第1页
第1页 / 共33页
第8章 图习题与解析.docx_第2页
第2页 / 共33页
第8章 图习题与解析.docx_第3页
第3页 / 共33页
第8章 图习题与解析.docx_第4页
第4页 / 共33页
第8章 图习题与解析.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

第8章 图习题与解析.docx

《第8章 图习题与解析.docx》由会员分享,可在线阅读,更多相关《第8章 图习题与解析.docx(33页珍藏版)》请在冰豆网上搜索。

第8章 图习题与解析.docx

第8章图习题与解析

第七章图

7.1知识要点

7.2习题解析

7.2.1选择题

7.2.2判断题

第七章图

7.14

StatusBuild_AdjList(ALGraph&G)//输入有向图的顶点数,边数,顶点信息和边的信息建立邻接表

{

  InitALGraph(G);

  scanf("%d",&v);

  if(v<0)returnERROR;//顶点数不能为负

  G.vexnum=v;

  scanf("%d",&a);

  if(a<0)returnERROR;//边数不能为负

  G.arcnum=a;

  for(m=0;m

    G.vertices[m].data=getchar();//输入各顶点的符号

  for(m=1;m<=a;m++)

  {

    t=getchar();h=getchar();//t为弧尾,h为弧头

    if((i=LocateVex(G,t))<0)returnERROR;

    if((j=LocateVex(G,h))<0)returnERROR;//顶点未找到

    p=(ArcNode*)malloc(sizeof(ArcNode));

    if(!

G.vertices.[i].firstarc)G.vertices[i].firstarc=p;

    else

    {

      for(q=G.vertices[i].firstarc;q->nextarc;q=q->nextarc);

      q->nextarc=p;

    }

    p->adjvex=j;p->nextarc=NULL;

  }//while

  returnOK;

}//Build_AdjList

7.15

//本题中的图G均为有向无权图,其余情况容易由此写出

StatusInsert_Vex(MGraph&G,charv)//在邻接矩阵表示的图G上插入顶点v

{

  if(G.vexnum+1)>MAX_VERTEX_NUMreturnINFEASIBLE;

  G.vexs[++G.vexnum]=v;

  returnOK;

}//Insert_Vex

StatusInsert_Arc(MGraph&G,charv,charw)//在邻接矩阵表示的图G上插入边(v,w)

{

  if((i=LocateVex(G,v))<0)returnERROR;

  if((j=LocateVex(G,w))<0)returnERROR;

  if(i==j)returnERROR;

  if(!

G.arcs[i][j].adj)

  {

    G.arcs[i][j].adj=1;

    G.arcnum++;

  }

  returnOK;

}//Insert_Arc

StatusDelete_Vex(MGraph&G,charv)//在邻接矩阵表示的图G上删除顶点v

{

  n=G.vexnum;

  if((m=LocateVex(G,v))<0)returnERROR;

  G.vexs[m]<->G.vexs[n];//将待删除顶点交换到最后一个顶点

  for(i=0;i

  {

    G.arcs[i][m]=G.arcs[i][n];

    G.arcs[m][i]=G.arcs[n][i];//将边的关系随之交换

  }

  G.arcs[m][m].adj=0;

  G.vexnum--;

  returnOK;

}//Delete_Vex

分析:

如果不把待删除顶点交换到最后一个顶点的话,算法将会比较复杂,而伴随着大量元素的移动,时间复杂度也会大大增加.

StatusDelete_Arc(MGraph&G,charv,charw)//在邻接矩阵表示的图G上删除边(v,w)

{

  if((i=LocateVex(G,v))<0)returnERROR;

  if((j=LocateVex(G,w))<0)returnERROR;

  if(G.arcs[i][j].adj)

  {

    G.arcs[i][j].adj=0;

    G.arcnum--;

  }

  returnOK;

}//Delete_Arc

7.16

//为节省篇幅,本题只给出Insert_Arc算法.其余算法请自行写出.

StatusInsert_Arc(ALGraph&G,charv,charw)//在邻接表表示的图G上插入边(v,w)

{

  if((i=LocateVex(G,v))<0)returnERROR;

  if((j=LocateVex(G,w))<0)returnERROR;

  p=(ArcNode*)malloc(sizeof(ArcNode));

  p->adjvex=j;p->nextarc=NULL;

  if(!

G.vertices[i].firstarc)G.vertices[i].firstarc=p;

  else

  {

    for(q=G.vertices[i].firstarc;q->q->nextarc;q=q->nextarc)

      if(q->adjvex==j)returnERROR;//边已经存在

    q->nextarc=p;

  }

  G.arcnum++;

  returnOK;

}//Insert_Arc

7.17

//为节省篇幅,本题只给出较为复杂的Delete_Vex算法.其余算法请自行写出.

StatusDelete_Vex(OLGraph&G,charv)//在十字链表表示的图G上删除顶点v

{

  if((m=LocateVex(G,v))<0)returnERROR;

  n=G.vexnum;

  for(i=0;i

  {

    if(G.xlist[i].firstin->tailvex==m)//如果待删除的边是头链上的第一个结点

    {

      q=G.xlist[i].firstin;

      G.xlist[i].firstin=q->hlink;

      free(q);G.arcnum--;

    }

    else//否则

    {

      for(p=G.xlist[i].firstin;p&&p->hlink->tailvex!

=m;p=p->hlink);

      if(p)

      {

        q=p->hlink;

        p->hlink=q->hlink;

        free(q);G.arcnum--;

      }

    }//else

  }//for

  for(i=0;i

  {

    if(G.xlist[i].firstout->headvex==m)//如果待删除的边是尾链上的第一个结点

    {

      q=G.xlist[i].firstout;

      G.xlist[i].firstout=q->tlink;

      free(q);G.arcnum--;

    }

    else//否则

    {

      for(p=G.xlist[i].firstout;p&&p->tlink->headvex!

=m;p=p->tlink);

      if(p)

      {

        q=p->tlink;

        p->tlink=q->tlink;

        free(q);G.arcnum--;

      }

    }//else

  }//for

  for(i=m;i

  {

    G.xlist[i]=G.xlist[i+1];//修改表头向量

    for(p=G.xlist[i].firstin;p;p=p->hlink)

      p->headvex--;

    for(p=G.xlist[i].firstout;p;p=p->tlink)

      p->tailvex--;//修改各链中的顶点序号

  }

  G.vexnum--;

  returnOK;

}//Delete_Vex

7.18

//为节省篇幅,本题只给出Delete_Arc算法.其余算法请自行写出.

StatusDelete_Arc(AMLGraph&G,charv,charw)////在邻接多重表表示的图G上删除边(v,w)

{

  if((i=LocateVex(G,v))<0)returnERROR;

  if((j=LocateVex(G,w))<0)returnERROR;

  if(G.adjmulist[i].firstedge->jvex==j)

    G.adjmulist[i].firstedge=G.adjmulist[i].firstedge->ilink;

  else

  {

    for(p=G.adjmulist[i].firstedge;p&&p->ilink->jvex!

=j;p=p->ilink);

    if(!

p)returnERROR;//未找到

    p->ilink=p->ilink->ilink;

  }//在i链表中删除该边

  if(G.adjmulist[j].firstedge->ivex==i)

    G.adjmulist[j].firstedge=G.adjmulist[j].firstedge->jlink;

  else

  {

    for(p=G.adjmulist[j].firstedge;p&&p->jlink->ivex!

=i;p=p->jlink);

    if(!

p)returnERROR;//未找到

    q=p->jlink;

    p->jlink=q->jlink;

    free(q);

  }//在i链表中删除该边

  G.arcnum--;

  returnOK;

}//Delete_Arc

7.19

StatusBuild_AdjMulist(AMLGraph&G)//输入有向图的顶点数,边数,顶点信息和边的信息建立邻接多重表

{

  InitAMLGraph(G);

  scanf("%d",&v);

  if(v<0)returnERROR;//顶点数不能为负

  G.vexnum=v;

  scanf(%d",&a);

  if(a<0)returnERROR;//边数不能为负

  G.arcnum=a;

  for(m=0;m

    G.adjmulist[m].data=getchar();//输入各顶点的符号

  for(m=1;m<=a;m++)

  {

    t=getchar();h=getchar();//t为弧尾,h为弧头

    if((i=LocateVex(G,t))<0)returnERROR;

    if((j=LocateVex(G,h))<0)returnERROR;//顶点未找到

    p=(EBox*)malloc(sizeof(EBox));

    p->ivex=i;p->jvex=j;

    p->ilink=NULL;p->jlink=NULL;//边结点赋初值

    if(!

G.adjmulist[i].firstedge)G.adjmulist[i].firstedge=p;

    else

    {

      q=G.adjmulist[i].firstedge;

      while(q)

      {

        r=q;

        if(q->ivex==i)q=q->ilink;

        elseq=q->jlink;

      }

      if(r->ivex==i)r->ilink=p;//注意i值既可能出现在边结点的ivex域中,

      elser->jlink=p;//又可能出现在边结点的jvex域中

    }//else//插入i链表尾部

    if(!

G.adjmulist[j].firstedge)G.adjmulist[j].firstedge=p;

    else

    {

      q=G.adjmulist[i].firstedge;

      while(q)

      {

        r=q;

        if(q->jvex==j)q=q->jlink;

        elseq=q->ilnk;

      }

      if(r->jvex==j)r->jlink=p;

      elser->ilink=p;

    }//else//插入j链表尾部

  }//for

  returnOK;

}//Build_AdjList

7.20

intPass_MGraph(MGraphG)//判断一个邻接矩阵存储的有向图是不是可传递的,是则返回1,否则返回0

{

  for(x=0;x

    for(y=0;y

      if(G.arcs[x][y])

      {

        for(z=0;z

          if(z!

=x&&G.arcs[y][z]&&!

G.arcs[x][z])return0;//图不可传递的条件

      }//if

  return1;

}//Pass_MGraph

分析:

本算法的时间复杂度大概是O(n^2*d).

7.21

intPass_ALGraph(ALGraphG)//判断一个邻接表存储的有向图是不是可传递的,是则返回1,否则返回0

{

  for(x=0;x

    for(p=G.vertices[x].firstarc;p;p=p->nextarc)

    {

      y=p->adjvex;

      for(q=G.vertices[y].firstarc;q;q=q->nextarc)

      {

        z=q->adjvex;

        if(z!

=x&&!

is_adj(G,x,z))return0;

      }//for

    }//for

}//Pass_ALGraph

intis_adj(ALGraphG,intm,intn)//判断有向图G中是否存在边(m,n),是则返回1,否则返回0

{

  for(p=G.vertices[m].firstarc;p;p=p->nextarc)

    if(p->adjvex==n)return1;

  return0;

}//is_adj

7.22

intvisited[MAXSIZE];//指示顶点是否在当前路径上

intexist_path_DFS(ALGraphG,inti,intj)//深度优先判断有向图G中顶点i到顶点j是否有路径,是则返回1,否则返回0

{

  if(i==j)return1;//i就是j

  else

  {

    visited[i]=1;

    for(p=G.vertices[i].firstarc;p;p=p->nextarc)

    {

      k=p->adjvex;

      if(!

visited[k]&&exist_path(k,j))return1;//i下游的顶点到j有路径

    }//for

  }//else

}//exist_path_DFS

7.23

intexist_path_BFS(ALGraphG,inti,intj)//广度优先判断有向图G中顶点i到顶点j是否有路径,是则返回1,否则返回0

{

  intvisited[MAXSIZE];

  InitQueue(Q);

  EnQueue(Q,i);

  while(!

QueueEmpty(Q))

  {

    DeQueue(Q,u);

    visited[u]=1;

    for(p=G.vertices[i].firstarc;p;p=p->nextarc)

    {

      k=p->adjvex;

      if(k==j)return1;

      if(!

visited[k])EnQueue(Q,k);

    }//for

  }//while

  return0;

}//exist_path_BFS

7.24

voidSTraverse_Nonrecursive(GraphG)//非递归遍历强连通图G

{

  intvisited[MAXSIZE];

  InitStack(S);

  Push(S,GetVex(S,1));//将第一个顶点入栈

  visit

(1);

  visited=1;

  while(!

StackEmpty(S))

  {

    while(Gettop(S,i)&&i)

    {

      j=FirstAdjVex(G,i);

      if(j&&!

visited[j])

      {

        visit(j);

        visited[j]=1;

        Push(S,j);//向左走到尽头

      }

    }//while

    if(!

StackEmpty(S))

    {

      Pop(S,j);

      Gettop(S,i);

      k=NextAdjVex(G,i,j);//向右走一步

      if(k&&!

visited[k])

      {

        visit(k);

        visited[k]=1;

        Push(S,k);

      }

    }//if

  }//while

}//Straverse_Nonrecursive

分析:

本算法的基本思想与二叉树的先序遍历非递归算法相同,请参考6.37.由于是强连通图,所以从第一个结点出发一定能够访问到所有结点.

7.25

见书后解答.

7.26

StatusTopoNo(ALGraphG)//按照题目要求顺序重排有向图中的顶点

{

  intnew[MAXSIZE],indegree[MAXSIZE];//储存结点的新序号

  n=G.vexnum;

  FindInDegree(G,indegree);

  InitStack(S);

  for(i=1;i

    if(!

indegree[i])Push(S,i);//零入度结点入栈

  count=0;

  while(!

StackEmpty(S))

  {

    Pop(S,i);

    new[i]=n--;//记录结点的拓扑逆序序号

    count++;

    for(p=G.vertices[i].firstarc;p;p=p->nextarc)

    {

      k=p->adjvex;

      if(!

(--indegree[k]))Push(S,k);

    }//for

  }//while

  if(count

  for(i=1;i<=n;i++)printf("OldNo:

%dNewNo:

%d\n",i,new[i])

  returnOK;

}//TopoNo

分析:

只要按拓扑逆序对顶点编号,就可以使邻接矩阵成为下三角矩阵.

7.27

intvisited[MAXSIZE];

intexist_path_len(ALGraphG,inti,intj,intk)//判断邻接表方式存储的有向图G的顶点i到j是否存在长度为k的简单路径

{

  if(i==j&&k==0)return1;//找到了一条路径,且长度符合要求

  elseif(k>0)

  {

    visited[i]=1;

    for(p=G.vertices[i].firstarc;p;p=p->nextarc)

    {

      l=p->adjvex;

      if(!

visited[l])

        if(exist_path_len(G,l,j,k-1))return1;//剩余路径长度减一

    }//for

    visited[i]=0;//本题允许曾经被访问过的结点出现在另一条路径中

  }//else

  return0;//没找到

}//exist_path_len

7.28

intpath[MAXSIZE],visited[MAXSIZE];//暂存遍历过程中的路径

intFind_All_Path(ALGraphG,intu,intv,intk)//求有向图G中顶点u到v之间的所有简单路径,k表示当前路径长度

{

  path[k]=u;//加入当前路径中

  visited[u]=1;

  if(u==v)//找到了一条简单路径

  {

    printf("Foundonepath!

\n");

    for(i=0;path[i];i++)printf("%d",path[i]);//打印输出

  }

  else

    for(p=G.vertices[u].firstarc;p;p=p->nextarc)

    {

      l=p->adjvex;

      if(!

visited[l])Find_All_Path(G,l,v,k+1);//继续寻找

    }

  visited[u]=0;

  path[k]=0;//回溯

}//Find_All_Path

main()

{

  ...

  Find_All_Path(G,u,v,0);//在主函数中初次调用,k值应为0

  ...

}//main

7.29

intGetPathNum_Len(ALGraphG,inti,intj,intlen)//求邻接表方式存储的有向图G的顶点i到j之间长度

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 判决书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1