图的深度优先搜索和广度优先搜索
图论中最粗暴的遍历方式非DFS和BFS莫属了。但是正是这种粗暴的方式,在笔试中被考察的概率非常的大。并且作为压轴题目,成为了一种危险的存在。a dangerous existence
好了,言归正传。图的存储方式,我们使用的是邻接矩阵matrix,顶点的编号一般从1开始,但是数组却从0开始。所以,如果编号为i的顶点和编号为j的顶点如果存在一条无向边,那么我们记为:matrix[i-1][j-1]
以上把定义都说明白了,下面,看代码。
1 const int vertexCount = 8; 2 byte[,] matrix = new byte[8, 8]; 3 bool start = true; 4 bool[] visit; 5 6 // 第一次进行时,初始化visit,表示所有顶点都没有遍历 7 void DFS_Init() 8 { 9 visit = new bool[vertexCount]; 10 for (int i = 0; i < vertexCount; i++) 11 { 12 visit[i] = false; 13 } 14 } 15 16 // 递归 17 void DFS_Recursive(int v) 18 { 19 Console.WriteLine(v); // 访问该顶点 20 visit[v-1] = true; 21 for (int i = 0; i < vertexCount; i++) 22 { 23 if (!visit[i] && matrix[v-1, i] == (byte)1) // 如果该顶点没有被访问过,并且与顶点v存在边Ev,i 24 { 25 DFS_Recursive(i+1); //数组下标为i,顶点编号为i+1 26 } 27 } 28 29 } 30 31 // 非递归 32 void DFS(int v) 33 { 34 Console.WriteLine(v); 35 visit[v] = true; 36 Stack<int> stack = new Stack<int>(); 37 stack.Push(v); 38 while (stack.Count > 0) 39 { 40 v = stack.Peek(); 41 int i; 42 for (i = 0; i < vertexCount; i++) 43 { 44 if (!visit[i] && matrix[v - 1, i] == (byte)1) // 如果该顶点没有被访问过,并且与顶点v存在边Ev,i 45 { 46 Console.WriteLine(i+1); 47 visit[i] = true; 48 stack.Push(i+1); 49 break; 50 } 51 52 } 53 if (i == vertexCount) 54 { 55 stack.Pop(); //如果通过该顶点不能再访问其他顶点时,出栈 56 } 57 } 58 }
广度优先搜索
1 void BFS(int v) 2 { 3 Console.WriteLine(v); 4 visit[v - 1] = true; 5 Queue<int> queue = new Queue<int>(); 6 queue.Enqueue(v); 7 while (queue.Count > 0) 8 { 9 v = queue.Dequeue(); 10 for (int i = 0; i < vertexCount; i++) 11 { 12 if (!visit[i] && matrix[v - 1, i] == (byte)1) 13 { 14 Console.WriteLine(i + 1); 15 visit[i] = true; 16 queue.Enqueue(i + 1); 17 } 18 } 19 } 20 }