今天我写了一个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()函数这一部分应该拿出来单独写在一个独立的头文件中,这样每当写关于图的程序时都可以引用该头文件。