深度優先搜索(Breadth First Search),相似於樹的層序遍歷,搜索模型是隊列,仍是如下面的無向圖爲例:html
實驗環境是Ubuntu 14.04 x86shell
僞代碼實現以下:spa
其中u
爲
v
的先輩或父母。
code
BFS(G, s)htm
for each vertex u ∈ V [G] - {s} do color[u] ← WHITE d[u] ← ∞ π[u] ← NIL //除了源頂點s以外,第1-4行置每一個頂點爲白色,置每一個頂點u的d[u]爲無窮大,置每一個頂點的父母爲NIL。 color[s] ← GRAY // 將源頂點s置爲灰色,這是由於在過程開始時,源頂點已被發現。 d[s] ← 0 π[s] ← NIL //將源頂點的父頂點置爲NIL。 Q ← Ø ENQUEUE(Q, s) //第八、9行,初始化隊列Q,使其僅含源頂點s。 while Q ≠ Ø do u ← DEQUEUE(Q) //肯定隊列頭部Q頭部的灰色頂點u,並將其從Q中去掉。 for each v ∈ Adj[u] //for循環考察u的鄰接表中的每一個頂點v do if color[v] = WHITE then color[v] ← GRAY d[v] ← d[u] + 1 π[v] ← u //u記爲該頂點的父母 ENQUEUE(Q, v) //插入隊列中 color[u] ← BLACK
隊列推薦使用鏈式隊列。blog
鄰接表實現:隊列
#include <stdio.h> #include <malloc.h> #define MAX_VERTEX_NUM 50 typedef char vertexType; typedef int edgeType; typedef int QueueElemType; /* 邊表 */ typedef struct ArcNode { int adjIndex; struct ArcNode *nextArc; edgeType weight; }ArcNode; /* 頂點表 */ typedef struct VNode { vertexType data; ArcNode *firstArc; }VNode, AdjList[MAX_VERTEX_NUM]; /* 圖結構 */ typedef struct { AdjList adjList; int vexNum; int edgeNum; }ALGraph; typedef struct QueueNode { QueueElemType data; struct QueueNode *next; }QueueNode; typedef struct { QueueNode *front; QueueNode *rear; }LinkQueue; int visit[MAX_VERTEX_NUM] = {0}; void initLinkQueue(LinkQueue *queue) { QueueNode *head = (QueueNode*)malloc(sizeof(QueueNode)); if(head == NULL) { printf("malloc failed\n"); return; } head->next = NULL; queue->front = queue->rear = head; return; } void insertLinkQueue(LinkQueue *queue, QueueElemType data) { QueueNode *newNode = (QueueNode *)malloc(sizeof(QueueNode)); if(NULL == newNode) { printf("malloc failed\n"); return; } newNode->data = data; newNode->next = NULL; queue->rear->next = newNode; queue->rear = newNode; return; } int deleteLinkQueue(LinkQueue *queue, QueueElemType *data) { QueueNode *p; if (queue->front == queue->rear) { printf("no element!\n"); return 0; } p = queue->front->next; *data = p->data; queue->front->next = p->next; if (p == queue->rear) { queue->rear = queue->front; } free(p); return 1; } void BFSTraverse(ALGraph G) { QueueElemType q; LinkQueue queue; ArcNode *adjEdge; int index = 0; initLinkQueue(&queue); for (int i = 0; i < G.vexNum; i++) { if (!visit[i]) { visit[i] = 1; printf("%c ", G.adjList[i].data); insertLinkQueue(&queue, i); while (deleteLinkQueue(&queue, &q)) { adjEdge = G.adjList[q].firstArc; while (adjEdge) { index = adjEdge->adjIndex; if (!visit[index]) { visit[index] = 1; printf("%c ", G.adjList[index].data); insertLinkQueue(&queue, index); } adjEdge = adjEdge->nextArc; } } } } } void CreateALGraph(ALGraph *G) { int i, j, k; ArcNode *e; int c; printf("輸入頂點數和邊數:\n"); scanf("%d %d", &G->vexNum, &G->edgeNum); setbuf(stdin, NULL); for (i = 0; i < G->vexNum; i++) { printf("輸入頂點信息:\n"); scanf("%c", &G->adjList[i].data); G->adjList[i].firstArc = NULL; while((c = getchar()) != '\n' && c != EOF); } for (k = 0; k < G->edgeNum; k++) { printf("輸入邊(vi,vj)的頂點序號i,j:\n"); scanf("%d %d", &i, &j); while((c = getchar()) != '\n' && c != EOF); e = (ArcNode*)malloc(sizeof(ArcNode)); if (NULL == e) { return; } e->adjIndex = j; e->nextArc = G->adjList[i].firstArc; G->adjList[i].firstArc = e; // double direction copy e = (ArcNode *)malloc(sizeof(ArcNode)); if (NULL == e) { return; } e->adjIndex = i; e->nextArc = G->adjList[j].firstArc; G->adjList[j].firstArc = e; } } int main(int argc, char const *argv[]) { ALGraph G; CreateALGraph(&G); BFSTraverse(G); return 0; }
運行結果: A F B G E I C H Dip
鄰接矩陣實現:element
#include <stdio.h> #include <malloc.h> #define MAX_VERTEX_NUM 50 typedef char vertexType; typedef int edgeType; typedef int QueueElemType; typedef struct { vertexType vexs[MAX_VERTEX_NUM]; edgeType arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; int vexNum; int edgeNum; }Graph; typedef struct QueueNode { QueueElemType data; struct QueueNode *next; }QueueNode; typedef struct { QueueNode *front; QueueNode *rear; }LinkQueue; int visit[MAX_VERTEX_NUM] = {0}; void initLinkQueue(LinkQueue *queue) { QueueNode *head = (QueueNode*)malloc(sizeof(QueueNode)); if(head == NULL) { printf("malloc failed\n"); return; } head->next = NULL; queue->front = queue->rear = head; return; } void insertLinkQueue(LinkQueue *queue, QueueElemType data) { QueueNode *newNode = (QueueNode *)malloc(sizeof(QueueNode)); if(NULL == newNode) { printf("malloc failed\n"); return; } newNode->data = data; newNode->next = NULL; queue->rear->next = newNode; queue->rear = newNode; return; } int deleteLinkQueue(LinkQueue *queue, QueueElemType *data) { QueueNode *p; if (queue->front == queue->rear) { printf("no element!\n"); return 0; } p = queue->front->next; *data = p->data; queue->front->next = p->next; if (p == queue->rear) { queue->rear = queue->front; } free(p); return 1; } void CreateALGraph(Graph *G) { int i, j, k; int c; printf("輸入頂點數和邊數:\n"); scanf("%d %d", &G->vexNum, &G->edgeNum); setbuf(stdin, NULL); for (i = 0; i < G->vexNum; i++) { printf("輸入第%d個頂點信息:\n", i + 1); scanf("%c", &G->vexs[i]); while((c = getchar()) != '\n' && c != EOF); } for (i = 0; i < G->vexNum; i++) { for (j = 0; j < G->vexNum; j++) { G->arc[i][j] = 0; } } for (k = 0; k < G->edgeNum; k++) { printf("輸入邊(vi,vj)的下標i,j:\n"); scanf("%d %d", &i, &j); while((c = getchar()) != '\n' && c != EOF); // set a default weight G->arc[i][j] = G->arc[j][i] = 1; } } void BFSTraverse(Graph G) { LinkQueue queue; QueueElemType q; initLinkQueue(&queue); for(int i = 0; i < G.vexNum; i++) { if (!visit[i]) { visit[i] = 1; printf("%c ", G.vexs[i]); insertLinkQueue(&queue, i); while (deleteLinkQueue(&queue, &q)) { for (int j = 0; j < G.vexNum; j++) { if (G.arc[q][j] == 1 && !visit[j]) { visit[j] = 1; printf("%c ", G.vexs[j]); insertLinkQueue(&queue, j); } } } } } } int main(int argc, char const *argv[]) { Graph G; CreateALGraph(&G); BFSTraverse(G); return 0; }
運行結果:A B F C G I E D Hget