从某源顶点触发,将源顶点置为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;
}