广度优先搜索

从某源顶点触发,将源顶点置为GRAY,将源顶点入队列,第一个顶点出队列,反问这个顶点的所有相邻顶点,如果相邻顶点是WHITE,则入队列,并置为GRAY,将本顶点置为BLACK. 取出队列的第一个顶点,继续上述步骤:


#include <stdio.h>
#include <stdlib.h>
#include "AdjacencyListGraph.h"
#include "Array_queue.h"


#define MAX_VERTEX   100
#define INT_MAX      0x7FFFFFFF

#define NIL          0


typedef enum
{
    WHITE = 0,
    GRAY  = 1,
    BLACK = 2
}COLOR;

static COLOR  color[MAX_VERTEX];

static  int  Distance[MAX_VERTEX];

static VertexType Parent[MAX_VERTEX];



void Init_BreadthFirstSearch(AdjacencyListLGraph *Graph)
{
    int i;

    for(i = 0; i < Graph->vexnum; i++)
    {
        color[i] = WHITE;
        Distance[i] = INT_MAX;
        Parent[i]  = NIL;
    }

    return;
}


int BreadthFirstSearch(AdjacencyListLGraph *Graph, VertexType SourceVertex)
{
    int srcIndex = SourceVertex - VERTEX_BASE;
    Array_Queue* queue = NULL;
    VertexType *element;
    VertexType  u, v;
    VNode*      uVnode = NULL;  
    AdjNode*    adjnode = NULL;
    int         weight = 0;

    
     if(NULL == Graph)
    {
        printf("input Graph is null %s, %d \n", __FILE__, __LINE__);

        return FALSE;
    }
    if(FALSE == AdjacencyListGraphIsIndexValid(Graph, SourceVertex))
    {
        printf("input SourceVertex(%d) is equal or bigger than vexnum(%d) %s, %d \n",SourceVertex, Graph->vexnum,  __FILE__, __LINE__);

        return FALSE;
    }

    Init_BreadthFirstSearch(Graph);

    color[srcIndex] = GRAY;
    Parent[srcIndex] = NIL;
    Distance[srcIndex] = 0;

    
    queue = ArrayQueueCreate(Graph->vexnum);
    if(NULL == queue)
    {
    
   printf("create queue failed %s, %d \n", __FILE__, __LINE__);
        return FALSE;
    }

    element = (VertexType *)malloc(sizeof(VertexType));

    *element = SourceVertex;
    //将源节点进入队列
    EnArrayQueue(queue, (void*) element);


    while(FALSE == ArrayQueueIsEmpty(queue))
    {
         //取出队列的头
        element = DeArrayQueue(queue);

        u = *element;
        free(element);

        //取得节点
        uVnode = AdjacencyListGraphGetVNodeByVexInd(Graph, u);
        if(NULL == uVnode)
        {
             printf("The vertex index(%d) is invalid %s, %d \n", u, __FILE__, __LINE__);

             ArrayQueueDestory(&queue, free);

             return FALSE;
             
        }

        //得到节点相连的第一个节点
        adjnode = AdjacencyListGraphGetAdjNodeFromVNode(uVnode);
        //将VNODE相连的边都访问一次
        while(NULL != adjnode)
        {
            //取得相邻节点的编号
            v = AdjacencyListGraphGetVertexInd(adjnode);
            weight = AdjacencyListGraphGetVertexWeight(adjnode);

            //如果是第一次访问这个顶点
            if(WHITE == color[v - VERTEX_BASE])
            {
                color[v - VERTEX_BASE] = GRAY;  //置为GRAY
                Distance[v - VERTEX_BASE] = Distance[u - VERTEX_BASE] + weight; //设置相邻节点的距离
                Parent[v - VERTEX_BASE] = u;
                element = (VertexType *)malloc(sizeof(VertexType));
                *element = v;
                EnArrayQueue(queue, (void*) element); //将相邻顶点入队列
                
            }
            adjnode = adjnode->next; //取下一个顶点
            
        }
        //这个顶点的相邻顶点都访问完毕;置为BLACK
        color[u - VERTEX_BASE] = BLACK;
    }


    ArrayQueueDestory(&queue, (freefunction)free);

    
    return TRUE; 
    
}


void BreadthFirstSearchPrintPath(AdjacencyListLGraph *Graph, 
                                    VertexType SourceVertex,VertexType DestVertex)
{
    if(SourceVertex == DestVertex)
    {
        printf("%d --> " ,SourceVertex);
    }
    else if(Parent[DestVertex - VERTEX_BASE] == NIL)
    {
        printf("There is no path from %d  to %d", SourceVertex, DestVertex);
    }
    else
    {
        BreadthFirstSearchPrintPath(Graph, SourceVertex,Parent[DestVertex - VERTEX_BASE]);
        printf("%d --> ",DestVertex );
    }

    return;
}

int main()
{
    AdjNode* node = NULL;
    AdjacencyListLGraph *Graph = NULL;
    int     vextexnum;
    int     srcindex, destindex, src;
    int     i;

    printf("please input the vertex number \n");
    scanf("%d", &vextexnum);

    Graph =   AdjacencyListGraphCreate(vextexnum,  0);

    printf("Please input the src index and dest index for edge and -1 for end\n");

    for(scanf("%d %d", &srcindex, &destindex); srcindex != -1; scanf("%d %d", &srcindex, &destindex))
    {
        node = AdjacencyListGraphCreateNode(destindex, 1, NULL);
        AdjacencyListGraphAddEdge(Graph, srcindex, node);
    }

    i = 0;

    AdjacencyListGraphPrint(Graph);
    
    printf("Please input the src index for search \n");

    scanf("%d", &src);


    BreadthFirstSearch(Graph, src);


    for(i = 0; i < Graph->vexnum; i++)
    {
        printf(" %d : %d  ",i+VERTEX_BASE , Distance[i]);
    }

    printf("\n\n");

    for(i = 0; i < Graph->vexnum; i++)
    {
        printf(" %d : %d  ",i+VERTEX_BASE , Parent[i]);
    }

    printf("\n\n");

    for(destindex = 1; destindex <= Graph->vexnum; destindex++)
    {
        BreadthFirstSearchPrintPath(Graph, src, destindex);

        printf(" NULL \n\n");
        
    }

    AdjacencyListGraphRelease(&Graph, (freefun)free);


    return 1;
    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值