今天我写了一个BFS(广度优先搜索)算法的程序,在此展示出来。
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <vector>
4 #include <queue>
5 using namespace std; 6
7 const int max_dist=9999; 8 const int invalid_p=-1; 9
10 struct adjNode{ 11 int node; 12 struct adjNode *next; 13 }; 14
15 enum Color{w, g, b}; 16
17 struct BFS_struct{ 18 Color color; 19 int d; 20 int parent; 21 }; 22
23 /*图的矩阵表示向邻接表表示的转换*/
24 void matrixToAdjlist(int *matrix, adjNode *adjList, int n){ 25 int i, j; 26 adjNode *tempNode; 27 for(i=0; i<n; ++i){ 28 adjList[i].node=i; 29 adjList[i].next=NULL; 30
31 for(j=n-1; j>=0; j--){ 32 if(*(matrix+i*n+j)== 1){ 33 tempNode=(adjNode *)malloc(sizeof(adjNode)); 34 tempNode->next=adjList[i].next; 35 tempNode->node=j; 36 adjList[i].next=tempNode; 37 } 38 } 39 } 40 } 41
42 /*释放邻接表中分配的空间*/
43 void freeAdjList(adjNode *adjList, int n){ 44 int i; 45 adjNode *tempNode; 46
47 for(i=0; i<n; ++i){ 48 tempNode=adjList[i].next; 49 while(tempNode != NULL){ 50 adjList[i].next=tempNode->next; 51 free(tempNode); 52 tempNode=adjList[i].next; 53 } 54 } 55
56 free(adjList); 57 } 58
59 /*BFS算法*/
60 void BFS(adjNode *adjList, BFS_struct *bfsArray, int s, int n){ 61 int i, temp1, temp2; 62 adjNode *tempNode; 63 //vector<int> bfsQueue;
64 queue<int> bfsQueue; 65 for(i=0; i<n; ++i){ 66 bfsArray[i].color=w; 67 bfsArray[i].d=max_dist; 68 bfsArray[i].parent=invalid_p; 69 } 70 bfsArray[s].color=g; 71 bfsArray[s].d=0; 72 bfsArray[s].parent=invalid_p; 73
74 bfsQueue.push(s); 75 while(!bfsQueue.empty()){ 76 temp1=bfsQueue.front(); 77 bfsQueue.pop(); 78 tempNode=adjList[temp1].next; 79 while(tempNode != NULL){ 80 temp2=tempNode->node; 81 if(bfsArray[temp2].color == w){ 82 bfsArray[temp2].color=g; 83 bfsArray[temp2].d=bfsArray[temp1].d+1; 84 bfsArray[temp2].parent=temp1; 85 bfsQueue.push(temp2); 86 } 87
88 tempNode=tempNode->next; 89 } 90
91 bfsArray[temp1].color=b; 92 } 93
94 } 95
96 /*输出BFS学习之后从源节点s到各个节点的最短路径*/
97 void print_path(BFS_struct *bfsArray, int s, int u){ 98 if(s == u) 99 printf("%d ", s); 100 else if(bfsArray[u].parent == invalid_p) 101 printf("There is no path form %d to %d", s, u); 102 else{ 103 print_path(bfsArray, s, bfsArray[u].parent); 104 printf("%d ", u); 105 } 106 } 107
108 int main(){ 109 int *matrix; 110 adjNode *adjList, *tempNode; 111 int nodeNum=0, i, j, startpoint=0; 112 BFS_struct *bfsArray; 113
114 printf("Input node number: "); 115 scanf("%d", &nodeNum); 116
117 matrix=(int *)malloc(sizeof(int)*nodeNum*nodeNum); 118 adjList=(adjNode *)malloc(sizeof(adjNode)*nodeNum); 119
120 for(i=0; i<nodeNum; ++i) 121 for(j=0; j<nodeNum; ++j) 122 scanf("%d", matrix+i*nodeNum+j); 123
124 /*以矩阵形式输出图*/
125 printf("matrix: \n"); 126 for(i=0; i<nodeNum; ++i){ 127 for(j=0; j<nodeNum; ++j) 128 printf("%d ", *(matrix+i*nodeNum+j)); 129 printf("\n"); 130 } 131
132 matrixToAdjlist(matrix, adjList, nodeNum); 133 /*以邻接表形式输出图*/
134 printf("adjacency list: \n"); 135 for(i=0; i<nodeNum; ++i){ 136 printf("node %d:", adjList[i].node); 137 tempNode=adjList[i].next; 138 while(tempNode != NULL){ 139 printf("->%d", tempNode->node); 140 tempNode=tempNode->next; 141 } 142 printf("\n"); 143 } 144
145 printf("Please intput startpoint: "); 146 scanf("%d", &startpoint); 147 bfsArray=(BFS_struct *)malloc(sizeof(BFS_struct)*nodeNum); 148 BFS(adjList, bfsArray, startpoint, nodeNum); 149 for(i=0; i<nodeNum; ++i){ 150 printf("path form %d to %d: ", startpoint, i); 151 print_path(bfsArray, startpoint, i); 152 printf("\n"); 153 } 154
155 free(matrix); 156 free(bfsArray); 157 freeAdjList(adjList, nodeNum); 158 return 0; 159 }
在程序中,我把图的表示方式(邻接矩阵和邻接表)与BFS算法用到的数据结构(主要是BFS_struct)分离开来,没有把BFS_struct写到adjList中,主要是考虑到邻接矩阵和邻接表的通用性。在别的程序中matrixToAdjlist()函数也可使用,但是BFS_struct数据结构就不一定能用得到(例如DFS算法)。其实把图的表示方式和matrixToAdjlist()函数这一部分应该拿出来单独写在一个独立的头文件中,这样每当写关于图的程序时都可以引用该头文件。