NOJ-基于图的广度优先搜索策略-西工大数据结构

    放假前课上讲了广度搜索,这两天一直在复习电路基础,今天晚上才把这道题给写了,题目如下:


    这个题就是把上一道题的深度变成广度了,输入构建图都没有变,所以我就稍微改了一下上次的代码,加了几个队列函数。

    先把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)--;//队列个数减少
}

    以上就是我的实现。










猜你喜欢

转载自blog.csdn.net/qq_30180107/article/details/80152580