图算法之BFS
深度優先搜索(Breadth? First Search),類似于樹的層序遍歷,搜索模型是隊列,還是以下面的無向圖為例:
實驗環境是Ubuntu 14.04 x86
?
偽代碼實現如下:
其中u 為 v 的先輩或父母。
BFS(G, s)
for each vertex u ∈ V [G] - {s}do color[u] ← WHITEd[u] ← ∞π[u] ← NIL //除了源頂點s之外,第1-4行置每個頂點為白色,置每個頂點u的d[u]為無窮大,置每個頂點的父母為NIL。 color[s] ← GRAY // 將源頂點s置為灰色,這是因為在過程開始時,源頂點已被發現。 d[s] ← 0 π[s] ← NIL //將源頂點的父頂點置為NIL。 Q ← ? ENQUEUE(Q, s) //第8、9行,初始化隊列Q,使其僅含源頂點s。 while Q ≠ ?do u ← DEQUEUE(Q) //確定隊列頭部Q頭部的灰色頂點u,并將其從Q中去掉。for each v ∈ Adj[u] //for循環考察u的鄰接表中的每個頂點vdo if color[v] = WHITEthen color[v] ← GRAY d[v] ← d[u] + 1 π[v] ← u //u記為該頂點的父母ENQUEUE(Q, v) //插入隊列中color[u] ← BLACK?
隊列推薦使用鏈式隊列。
鄰接表實現:
#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 copye = (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 D
?
鄰接矩陣實現:
#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 weightG->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 H
轉載于:https://www.cnblogs.com/freedreamnight/p/3906047.html
總結
- 上一篇: 微信转账记录保留几年
- 下一篇: 台式宏基电脑怎么启动进系统吗 如何启动台