第十章第十六题 POWERBY KTL

//16.利用图的深度优先搜索和广度优先搜索各写一个算法,
//辨别以邻接表方式表示的有向图中是否存在由顶点Vi到顶点Vj的路径(i!=j).
//深度优先(第一个函数Route)
//广度优先(第二个函数Route,需要去调注释同时把深度优先函数注释掉;
//程序输入,参考书本P225页图10-6
//输入顶点信息为1234(回车);
//输入边数为4;
//输入第一边:1 2
//输入第二边:1 3
//输入第三边:3 4
//输入第四边:4 1
//按#结束测试程序;
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"

#define n 4
typedef char vextype;
typedef struct node1   //由于与队列结点定义发生冲突,因此改为node1;
{
 int adjvex;
 struct node1 *pNext;
}edgenode;
typedef struct
{
 vextype vertex;
 edgenode *link;
}vexnode;

vexnode ga[n];
int visited[n]={0};

void CreatList(vexnode ga[])
{
 int i,j,k,e,h;
 edgenode *s;
 printf("请输入顶点信息:");
 for(i=0;i<n;i++)
 {
  ga[i].vertex=getchar();
  ga[i].link=NULL;
 }
 printf("请输入有向边的数目:");
 scanf("%d",&e);
 h=1;
 for(k=0;k<e;k++)
 {
  printf("请输入第%d个边的i,j:",h++);
  scanf("%d %d",&i,&j);
  s=(edgenode*)malloc(sizeof(edgenode));
  s->adjvex=j;
  s->pNext=ga[i].link;
  ga[i].link=s;
 }
 return;
}

int flag=0;//标志为全局变量

//以下函数为按深度优先判断是否存在路径(注意下面的注释)
///*
void Route(int i,int j)
{
 edgenode *p;
 if(i==j)
 {
  flag=1;
  return;
 }
 visited[i]=1;
 p=ga[i].link;
 while(p!=NULL)
 {
  if(visited[p->adjvex]==0)
   Route(p->adjvex,j);
  p=p->pNext;
 }
 return;
}
//*/
//以下函数为按广度优先判断是否存在路径;
//附队列程序  把注释去掉即可调用广度优先判断是否存在路径;
/*

typedef char datatype;

typedef struct node2
{
 datatype data;
 struct node2 * pNext;
}linklist;

typedef struct
{
 linklist *front,*rear;
}linkqueue;

void SETNULLQL(linkqueue *q)
{
 q->front=(linklist*)malloc(sizeof(linklist));
 q->front->pNext=NULL;
 q->rear=q->front;
}//置空队

bool EMPTYQL(linkqueue*q)
{
 if(q->front==q->rear)
  return true;
 else return false;
}//判断队空

datatype FRONTQL(linkqueue*q)
{
 if(EMPTYQL(q))
 {
  printf("队空");
  return -1;
 }
 else return(q->front->pNext->data);
}//取队头元素

void ENQUEUEQL(linkqueue *q,datatype x)
{
 q->rear->pNext=(linklist *)malloc(sizeof(linklist));
 q->rear=q->rear->pNext;
 q->rear->data=x;
 q->rear->pNext=NULL;
}//入队

datatype DEQUEUEQL(linkqueue*q)
{
 datatype temp;
 linklist * s;
 if(EMPTYQL(q))
 {
  printf("队空");
  return -1;
 }
 else{
  s=q->front->pNext;
  if(s->pNext==NULL)
  {
   q->front->pNext=NULL;
   q->rear=q->front;
  }
  else q->front->pNext=s->pNext;
  temp=s->data;
  free(s);
  return(temp);
 }
}//删除队头元素并返回队头元素

void Route(int i,int j)
{
 int k;
 edgenode *p;
 linkqueue *Q;
 Q=(linkqueue*)malloc(sizeof(linkqueue));
 SETNULLQL(Q);
 if(i==j){
  flag=1;
  return;
 }
 visited[i]=1;
 ENQUEUEQL(Q,i);
 while(!EMPTYQL(Q))
 {
  k=DEQUEUEQL(Q);
  p=ga[k].link;
  while(p!=NULL)
  {
   if(visited[p->adjvex]!=1)
   {
    if(p->adjvex==j){    //与深度优先不同,关键这里要用的是p->adjvex==j;
     flag=1;
     return;
    }
    visited[p->adjvex]=1;
    ENQUEUEQL(Q,p->adjvex);
   }
   p=p->pNext;
  }
 }
}

*/
int main()
{
 char ch;
 int i,j,k;
 printf("本程序为测试i到j是否有路径.../n");
 CreatList(ga);
 while(ch!='#')
 {
  printf("请输入要测试的顶点Vi与Vj的下标:");
  scanf("%d %d",&i,&j);
  Route(i,j);
  if(flag)
   printf("存在路径.../n");
  else
   printf("不存在路径.../n");
  printf("如果退出请输入#...按任意键继续.../n");
  ch=getch();
  flag=0;
  for(k=0;k<n;k++)
   visited[k]=0;
 }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值