廣度優先遍曆是連通圖的一種遍曆策略。其基本思想如下:
1、某個頂點V0出發,並訪問此頂點;
2、從V0出發,訪問V0的各個未曾訪問的鄰接點W1,W2,…,Wk;然後,依次從W1,W2,…,Wk出發訪問各自未被訪問的鄰接點;
3、重複步驟2,直到全部頂點都被訪問為止。
例如中:1.從0開始,首先找到0的關聯頂點3,42.由3出發,找到1,2;由4出發,找到1,但是1已經遍曆過,所以忽略。3.由1出發,沒有關聯頂點;由2出發,沒有關聯頂點。所以最後順序是0,3,4,1,2c語言實現如下:(使用鄰接矩陣儲存)
#include <stdio.h>#include <malloc.h>#define VERTEXNUM 5//隊列的元素typedef struct qElement{ int value; struct qElement* pre; struct qElement* next;}st_qElement;//隊列的前端和後端,最後一個入隊列的元素為rear,第一個出隊列的元素為frontst_qElement* front = NULL;st_qElement* rear = NULL;void createGraph(int (*edge)[VERTEXNUM], int start, int end);void displayGraph(int (*edge)[VERTEXNUM]);void BFT(int (*edge)[VERTEXNUM],int* vertexStatusArr);void BFTcore(int (*edge)[VERTEXNUM],int i,int* vertexStatusArr);void putQueue(int vertex);int* getQueue();void putRelatedInQueue(int (*edge)[VERTEXNUM], int vertex);int main(void){//動態建立存放邊的二維數組 int (*edge)[VERTEXNUM] = (int (*)[VERTEXNUM])malloc(sizeof(int)*VERTEXNUM*VERTEXNUM); int i,j; for(i=0;i<VERTEXNUM;i++){ for(j=0;j<VERTEXNUM;j++){ edge[i][j] = 0; } }//存放頂點的遍曆狀態,0:未遍曆,1:已遍曆 int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM); for(i=0;i<VERTEXNUM;i++){ vertexStatusArr[i] = 0; } printf("after init:\n"); displayGraph(edge);//建立圖 createGraph(edge,0,3); createGraph(edge,0,4); createGraph(edge,3,1); createGraph(edge,3,2); createGraph(edge,4,1); printf("after create:\n"); displayGraph(edge);//廣度優先遍曆 BFT(edge,vertexStatusArr); free(edge); return 0;}//建立圖void createGraph(int (*edge)[VERTEXNUM], int start, int end){ edge[start][end] = 1;}//列印儲存的圖void displayGraph(int (*edge)[VERTEXNUM]){ int i,j; for(i=0;i<VERTEXNUM;i++){ for(j=0;j<VERTEXNUM;j++){ printf("%d ",edge[i][j]); } printf("\n"); }}//廣度優先遍曆void BFT(int (*edge)[VERTEXNUM], int* vertexStatusArr){ printf("start BFT graph:\n"); int i; for(i=0;i<VERTEXNUM;i++){ BFTcore(edge,i,vertexStatusArr); } printf("\n");}void BFTcore(int (*edge)[VERTEXNUM],int i,int* vertexStatusArr){ putQueue(i); int* qeValue = NULL; while((qeValue = getQueue()) != NULL){ if(vertexStatusArr[*qeValue] == 0){ printf("%d ",*qeValue); vertexStatusArr[*qeValue] = 1; putRelatedInQueue(edge, *qeValue); } free(qeValue); qeValue = NULL; }}//將元素放到隊列中void putQueue(int vertex){ st_qElement* qe = (st_qElement*)malloc(sizeof(st_qElement)); qe->value = vertex; qe->next = NULL; qe->pre = NULL; if(front == NULL || rear == NULL){ front = rear = qe; }else{ rear->next = qe; qe->pre = rear; rear = qe; }}//從隊列中擷取一個元素int* getQueue(){ if(front == NULL || rear == NULL){ return NULL; }else{ int* res = (int*)malloc(sizeof(int)); *res = front->value; st_qElement* p = front; front = front->next; if(front == NULL){ rear = front; }else{ front->pre = NULL; } free(p); p = NULL; return res; }}//將頂點關聯的元素放到隊列中void putRelatedInQueue(int (*edge)[VERTEXNUM], int vertex){ int i; for(i=0;i<VERTEXNUM;i++){ if(edge[vertex][i] == 1){ putQueue(i); } }}c語言實現如下:(使用鄰接表格儲存體)
#include <stdio.h>#include <malloc.h>#define VERTEXNUM 5//存放頂點的鄰接表元素typedef struct edge{ int vertex; struct edge* next;}st_edge;//隊列的元素typedef struct qElement{ int value; struct qElement* pre; struct qElement* next;}st_qElement;//隊列的前端和後端,最後一個入隊列的元素為rear,第一個出隊列的元素為frontst_qElement* front = NULL;st_qElement* rear = NULL;void createGraph(st_edge** edge, int start, int end);void displayGraph(st_edge** edge);void delGraph(st_edge** edge);void BFT(st_edge** edge,int* vertexStatusArr);void BFTcore(st_edge** edge,int i,int* vertexStatusArr);void putQueue(int vertex);int* getQueue();void putRelatedInQueue(st_edge** edge, int vertex);int main(void){//動態建立存放邊的指標數組 st_edge** edge = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM); int i; for(i=0;i<VERTEXNUM;i++){ edge[i] = NULL; }//存放頂點的遍曆狀態,0:未遍曆,1:已遍曆 int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM); for(i=0;i<VERTEXNUM;i++){ vertexStatusArr[i] = 0; } printf("after init:\n"); displayGraph(edge);//建立圖 createGraph(edge,0,3); createGraph(edge,0,4); createGraph(edge,3,1); createGraph(edge,3,2); createGraph(edge,4,1); printf("after create:\n"); displayGraph(edge);//廣度優先遍曆 BFT(edge,vertexStatusArr);//釋放鄰接表佔用的記憶體 delGraph(edge); edge = NULL; free(vertexStatusArr); vertexStatusArr = NULL; return 0;}//建立圖void createGraph(st_edge** edge, int start, int end){ st_edge* newedge = (st_edge*)malloc(sizeof(st_edge)); newedge->vertex = end; newedge->next = NULL; edge = edge + start; while(*edge != NULL){ edge = &((*edge)->next); } *edge = newedge;}//列印儲存的圖void displayGraph(st_edge** edge){ int i; st_edge* p; for(i=0;i<VERTEXNUM;i++){ printf("%d:",i); p = *(edge+i); while(p != NULL){ printf("%d ",p->vertex); p = p->next; } printf("\n"); }}//釋放鄰接表佔用的記憶體void delGraph(st_edge** edge){ int i; st_edge* p; st_edge* del; for(i=0;i<VERTEXNUM;i++){ p = *(edge+i); while(p != NULL){ del = p; p = p->next; free(del); } edge[i] = NULL; } free(edge);}//廣度優先遍曆void BFT(st_edge** edge,int* vertexStatusArr){ printf("start BFT graph:\n"); int i; for(i=0;i<VERTEXNUM;i++){ BFTcore(edge,i,vertexStatusArr); } printf("\n");}void BFTcore(st_edge** edge,int i,int* vertexStatusArr){ putQueue(i); int* qeValue = NULL; while((qeValue = getQueue()) != NULL){ if(vertexStatusArr[*qeValue] == 0){ printf("%d ",*qeValue); vertexStatusArr[*qeValue] = 1; putRelatedInQueue(edge, *qeValue); } free(qeValue); qeValue = NULL; }}//將元素放到隊列中void putQueue(int vertex){ st_qElement* qe = (st_qElement*)malloc(sizeof(st_qElement)); qe->value = vertex; qe->next = NULL; qe->pre = NULL; if(front == NULL || rear == NULL){ front = rear = qe; }else{ rear->next = qe; qe->pre = rear; rear = qe; }}//從隊列中擷取一個元素int* getQueue(){ if(front == NULL || rear == NULL){ return NULL; }else{ int* res = (int*)malloc(sizeof(int)); *res = front->value; st_qElement* p = front; front = front->next; if(front == NULL){ rear = front; }else{ front->pre = NULL; } free(p); p = NULL; return res; }}//將頂點關聯的元素放到隊列中void putRelatedInQueue(st_edge** edge, int vertex){ st_edge* p = *(edge+vertex); while(p != NULL){ putQueue(p->vertex); p = p->next; }}