放假前课上讲了广度搜索,这两天一直在复习电路基础,今天晚上才把这道题给写了,题目如下:
这个题就是把上一道题的深度变成广度了,输入构建图都没有变,所以我就稍微改了一下上次的代码,加了几个队列函数。
先把3 3 1 2 3 1 2 1 3 2 1构建为下面的图:
广度搜索其实是一种队列的操作,每次取队列头,把队列头边表的所有节点入队,然后把队列头出队列,循环直到队列头是所找节点或队列空(没找到),寻找1 3的步骤如下图:
以下是我的实现:
#include <stdio.h>
#include <stdlib.h>
struct edgeNode
{
int headVex;
struct edgeNode *next;
};
struct vexNode
{
int vex;
struct edgeNode *head;
};
struct graphList
{
struct vexNode vex[3000];
int vexNum;
int edgeNum;
};
struct edgeNodeQueue
{
int nodeQueue[3000];
int n;
};
void run ();
void createNewGraphList (struct graphList *gList);
void clearVexNodes (struct graphList *gList);
int findVex (int vex,struct graphList *gList);
void createNewEdgeNode (int n,struct graphList *gList);
void existWay (struct graphList *gList);
int breadthFirstSearch (char flags[],struct graphList *gList,int cur,int find,struct edgeNodeQueue *queue);
void clearQueue(struct edgeNodeQueue *queue);
void pushQueue (struct edgeNodeQueue *queue,int vex);
void unshiftQueue (struct edgeNodeQueue *queue);
int main()
{
run ();
return 0;
}
void run ()
{
struct graphList gList;
createNewGraphList (&gList);
existWay (&gList);
}
void createNewGraphList (struct graphList *gList)
{
scanf ("%d%d",&(gList->vexNum),&(gList->edgeNum));
clearVexNodes (gList);
int i;
for (i=0;i<gList->vexNum;i++)
{
scanf ("%d",&(gList->vex[i].vex));
}
int vex,n;
for (i=0;i<gList->edgeNum;i++)
{
scanf ("%d",&vex);
n=findVex (vex,gList);
createNewEdgeNode (n,gList);
}
}
void clearVexNodes (struct graphList *gList)
{
int i;
for (i=0;i<gList->vexNum;i++)
{
gList->vex[i].vex=0;
gList->vex[i].head=NULL;
}
}
int findVex (int vex,struct graphList *gList)
{
int i;
for (i=0;i<gList->vexNum;i++)
{
if (vex==gList->vex[i].vex)
{
return i;
}
}
return -1;
}
void createNewEdgeNode (int n,struct graphList *gList)
{
struct edgeNode *p,*q;
int vex;
p=(struct edgeNode *)malloc(sizeof(struct edgeNode));
scanf ("%d",&vex);
p->headVex=findVex (vex,gList);
p->next=NULL;
if (gList->vex[n].head==NULL)
{
gList->vex[n].head=p;
}
else
{
q=gList->vex[n].head;
while (q->next)
{
q=q->next;
}
q->next=p;
}
}
void existWay (struct graphList *gList)
{
int vi,cur,find;
scanf ("%d%d",&vi,&find);
cur=findVex (vi,gList);
char flags[3000]={0};
struct edgeNodeQueue queue;
clearQueue (&queue);
if (breadthFirstSearch (flags,gList,cur,find,&queue))
{
printf ("yes");
}
else
{
printf ("no");
}
}
int breadthFirstSearch (char flags[],struct graphList *gList,int cur,int find,struct edgeNodeQueue *queue)
{
int headVex;
struct edgeNode *p;
headVex=cur;
pushQueue(queue,headVex);
while (queue->n>=0)
{
headVex=queue->nodeQueue[0];
if (find==gList->vex[headVex].vex)
{
return 1;
}
if (flags[headVex]==0)
{
flags[headVex]=1;
p=gList->vex[headVex].head;
while (p)
{
pushQueue(queue,p->headVex);
p=p->next;
}
}
unshiftQueue(queue);
}
return 0;
}
void clearQueue(struct edgeNodeQueue *queue)
{
int i;
for (i=0;i<=2999;i++)
{
queue->nodeQueue[i]=0;
}
queue->n=-1;
}
void pushQueue (struct edgeNodeQueue *queue,int vex)
{
(queue->n)++;
queue->nodeQueue[queue->n]=vex;
}
void unshiftQueue (struct edgeNodeQueue *queue)
{
int i;
for (i=1;i<=queue->n;i++)
{
queue->nodeQueue[i-1]=queue->nodeQueue[i];
}
(queue->n)--;
}
void run ()
{
struct graphList gList;
createNewGraphList (&gList);//创建图
existWay (&gList);//是否存在路径
}
void createNewGraphList (struct graphList *gList)
{
scanf ("%d%d",&(gList->vexNum),&(gList->edgeNum));//输入顶点数,边数
clearVexNodes (gList);//清空所有顶点节点
int i;
for (i=0;i<gList->vexNum;i++)//遍历输入顶点
{
scanf ("%d",&(gList->vex[i].vex));
}
int vex,n;
for (i=0;i<gList->edgeNum;i++)//遍历构建边表
{
scanf ("%d",&vex);//输入边尾
n=findVex (vex,gList);//得到边尾节点位置
createNewEdgeNode (n,gList);//在边尾表中创建新的边节点
}
}
void clearVexNodes (struct graphList *gList)
{
int i;
for (i=0;i<gList->vexNum;i++)//遍历清空
{
gList->vex[i].vex=0;
gList->vex[i].head=NULL;
}
}
int findVex (int vex,struct graphList *gList)
{
int i;
for (i=0;i<gList->vexNum;i++)//遍历寻找
{
if (vex==gList->vex[i].vex)//找到就返回位置
{
return i;
}
}
return -1;//否则返回-1
}
void createNewEdgeNode (int n,struct graphList *gList)
{
struct edgeNode *p,*q;
int vex;
p=(struct edgeNode *)malloc(sizeof(struct edgeNode));//创建边节点
scanf ("%d",&vex);
p->headVex=findVex (vex,gList);//存入边头节点位置
p->next=NULL;//next设为空
if (gList->vex[n].head==NULL)//若该节点边表为空
{
gList->vex[n].head=p;//表头就是新边节点
}
else//若不空
{
q=gList->vex[n].head;
while (q->next)//找到最后一个边节点
{
q=q->next;
}
q->next=p;
}//加入新边节点
}
void existWay (struct graphList *gList)
{
int vi,cur,find;
scanf ("%d%d",&vi,&find);//输入路径起点和终点
cur=findVex (vi,gList);//起点位置
char flags[3000]={0};//初始化路径记录数组
struct edgeNodeQueue queue;
clearQueue (&queue);//清空队列
if (breadthFirstSearch (flags,gList,cur,find,&queue))
{
printf ("yes");//找到
}
else
{
printf ("no");//未找到
}
}
int breadthFirstSearch (char flags[],struct graphList *gList,int cur,int find,struct edgeNodeQueue *queue)
{
int headVex;
struct edgeNode *p;
headVex=cur;
pushQueue(queue,headVex);//循环准备
while (queue->n>=0)//进入循环,队空结束循环
{
headVex=queue->nodeQueue[0];//队列头
if (find==gList->vex[headVex].vex)//若找到,返回1
{
return 1;
}
if (flags[headVex]==0)//若此节点未走过
{
flags[headVex]=1;//标记为走过
p=gList->vex[headVex].head;
while (p)//将边表中每一个节点入队
{
pushQueue(queue,p->headVex);
p=p->next;
}
}
unshiftQueue(queue);//队列头出队列
}
return 0;//搜索完未找到,返回0
}
void clearQueue(struct edgeNodeQueue *queue)
{
int i;
for (i=0;i<=2999;i++)//遍历清空
{
queue->nodeQueue[i]=0;
}
queue->n=-1;
}
void pushQueue (struct edgeNodeQueue *queue,int vex)
{
(queue->n)++;//队列个数增加
queue->nodeQueue[queue->n]=vex;//入队
}
void unshiftQueue (struct edgeNodeQueue *queue)
{
int i;
for (i=1;i<=queue->n;i++)//队列头出队列
{
queue->nodeQueue[i-1]=queue->nodeQueue[i];
}
(queue->n)--;//队列个数减少
}
以上就是我的实现。