搜索 图的类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> #include <list> #include <vector> #include <queue> using namespace std;class Graph { int V; vector<list<int >> adj; public : Graph (int V); void addEdge (int v, int w) ; void DFSUtil (int v, bool visited[]) ; void DFS (int v) ; void BFS (int s) ; }; Graph::Graph (int V) { this ->V = V; adj.resize (V); } void Graph::addEdge (int v, int w) { adj[v].push_back (w); }
DFS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void Graph::DFSUtil (int v, bool visited[]) { visited[v] = true ; cout << v << " " ; for (int i : adj[v]) { if (!visited[i]) DFSUtil (i, visited); } } void Graph::DFS (int v) { bool *visited = new bool [V]; for (int i = 0 ; i < V; i++) visited[i] = false ; DFSUtil (v, visited); delete [] visited; }
BFS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 void Graph::BFS (int s) { bool *visited = new bool [V]; for (int i = 0 ; i < V; i++) visited[i] = false ; queue<int > queue; visited[s] = true ; queue.push (s); while (!queue.empty ()) { s = queue.front (); cout << s << " " ; queue.pop (); for (int i : adj[s]) { if (!visited[i]) { visited[i] = true ; queue.push (i); } } } delete [] visited; }
测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int main () { Graph g (4 ) ; g.addEdge (0 , 1 ); g.addEdge (0 , 2 ); g.addEdge (1 , 2 ); g.addEdge (2 , 0 ); g.addEdge (2 , 3 ); g.addEdge (3 , 3 ); cout << "Following is Depth First Traversal (starting from vertex 2): \n" ; g.DFS (2 ); return 0 ; }
拓扑排序 只有有向无环图 能够进行拓扑排序
Kahn算法 Kahn算法 步骤: 1.计算所有顶点的入度 :入度是指指向该顶点的边的数量。 2.将所有入度为0的顶点 加入队列。 3.从队列中取出一个顶点,将其加入结果列表。 4.对于该顶点的所有邻接顶点,减少它们的入度。如果某个邻接顶点的入度变为 0,将其加入队列 。 5.重复步骤3和4,直到队列为空。 6.检查结果列表中的顶点数量是否等于图中的顶点数量。如果相等,则图是DAG , 结果列表即为拓扑排序;否则,图中存在环,无法进行拓扑排序 。
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 #include <iostream> #include <vector> #include <queue> #include <list> using namespace std;class Graph { int V; vector<list<int >> adj; public : Graph (int V); void addEdge (int v, int w) ; vector<int > topologicalSort () ; }; Graph::Graph (int V) { this ->V = V; adj.resize (V); } void Graph::addEdge (int v, int w) { adj[v].push_back (w); } vector<int > Graph::topologicalSort () { vector<int > inDegree (V, 0 ) ; for (int u = 0 ; u < V; ++u) { for (int v : adj[u]) { ++inDegree[v]; } } queue<int > q; for (int i = 0 ; i < V; ++i) { if (inDegree[i] == 0 ) { q.push (i); } } vector<int > topoOrder; while (!q.empty ()) { int u = q.front (); q.pop (); topoOrder.push_back (u); for (int v : adj[u]) { --inDegree[v]; if (inDegree[v] == 0 ) { q.push (v); } } } if (topoOrder.size () != V) { return {}; } return topoOrder; } int main () { Graph g (6 ) ; g.addEdge (5 , 2 ); g.addEdge (5 , 0 ); g.addEdge (4 , 0 ); g.addEdge (4 , 1 ); g.addEdge (2 , 3 ); g.addEdge (3 , 1 ); vector<int > topoOrder = g.topologicalSort (); if (topoOrder.empty ()) { cout << "Graph has at least one cycle. Topological sorting is not possible.\n" ; } else { cout << "Topological order: " ; for (int v : topoOrder) { cout << v << " " ; } cout << endl; } return 0 ; }
总结