图的遍历有深度优先和广度优先算法。
深度优先遍历可描述为一个递归算法。当到达顶点v时,具体操作是:
①访问(v);
②for(与v相邻的每个顶点w) 遍历(w);
//深度优先算法 template<int max_size> void Diagraph<max_size>::depth_first(void(*visit)(Vertex &)) const { bool visited[max_size]; //引入数组防止无限循环 Vertex v; for (all v in G) visited[v] = false; for (all v in G) { if (!visited[v]) { traverse(v, visited, visit); } } } template<int max_size> void Diagraph<max_size>::traverse(Vertex &v, bool visited[], void (*visit)(Vertex &)) const { Vertex w; visited[v] = true; (*visit)(v); for (all w adjacent to v) { if (!visited[w]) { traverse(w, visited, visit); } } }
广度优先算法借助队列,当访问v后, 将v相邻的仍未访问过的顶点加到队列后面,然后访问队列头:
//广度优先算法 template<int max_size> void Diagraph<max_size>::breadth_first(void (*visit)(Vertex &)) const { Queue q; bool visited[max_size]; Vertex v, w, x; for (all v in G) visited[v] = false; for (all v in G) { if (!visited[v]) { q.append(v); while (!q.empty()) { q.retrieve(w); if (!visited[w]) { visited[w] = true; (*visit) (w); for (all x adjacent to w) { q.append(x); } } q.serve(); } } } }
可以使用深度优先遍历和广度优先遍历确定拓扑次序。
深度优先遍历: 时间复杂度O(n+e)(n为图的定点数,e为图的边数)。
//深度优先算法 template<int graph_size> void Diagraph<graph_size>:: depth_sort(List<Vertex>&topological_order) { bool visited[graph_size]; Vertex v; for (v = 0; v < count; v++) visited[v] = false; topological_order.clear(); for (v = 0; v < count; v++) { if (!visited[v]) { recursive_depth_sort(v, visited, topological_order); } } } template<int max_size> void Diagraph<max_size>::recursive_depth_sort(Vertex v, bool *visited, List<Vertex>& topological_order) { visited[v] = true; int degree = neighbors[v].size(); for (int i = 0; i < degree; i++) { Vertex w; neighbors[v].retrieve(i, w); if (!visited[w]) { recursive_depth_sort(w, visited, topological_order); } } topological_order.insert(0, v); }
时间: 2024-10-03 02:43:09