当前位置: 面试刷题>> 拓扑排序 (经典算法题500道)


### 题目描述补充 **题目:拓扑排序** 给定一个有向无环图(DAG, Directed Acyclic Graph),请实现一个算法来对该图进行拓扑排序。拓扑排序是对图中的所有顶点进行排序,使得对于任何从顶点u到顶点v的有向边(u, v),u在排序中都出现在v之前。拓扑排序的结果可能不是唯一的。 ### 示例 假设有以下有向无环图: ``` 1 -> 2 1 -> 3 2 -> 3 ``` 一个可能的拓扑排序是 `[1, 2, 3]`,但 `[1, 3, 2]` 也是有效的,因为所有从u到v的边都满足u在v之前。 ### 解题思路 1. **入度表**:首先,计算图中每个顶点的入度(即指向该顶点的边的数量)。 2. **队列**:使用队列来存储入度为0的顶点,这些顶点可以作为拓扑排序的起始点。 3. **遍历**:从队列中取出一个顶点,将其添加到拓扑排序的结果中,并遍历该顶点的所有邻接点,将它们的入度减1。如果某个邻接点的入度变为0,则将其加入队列。 4. **检查**:如果最终拓扑排序的结果中顶点的数量与图中顶点的总数不一致,则说明图中存在环,无法进行拓扑排序。 ### 示例代码 #### PHP 示例 ```php function topologicalSort($graph) { $inDegree = array_fill_keys(array_keys($graph), 0); $adjList = []; foreach ($graph as $node => $neighbors) { foreach ($neighbors as $neighbor) { $inDegree[$neighbor]++; $adjList[$node][] = $neighbor; } } $queue = new SplQueue(); foreach ($inDegree as $node => $deg) { if ($deg === 0) { $queue->enqueue($node); } } $result = []; while (!$queue->isEmpty()) { $node = $queue->dequeue(); $result[] = $node; foreach ($adjList[$node] as $neighbor) { $inDegree[$neighbor]--; if ($inDegree[$neighbor] === 0) { $queue->enqueue($neighbor); } } } return count($result) === count($graph) ? $result : false; // 存在环则返回false } // 示例用法 $graph = [ 1 => [2, 3], 2 => [3], ]; print_r(topologicalSort($graph)); ``` #### Python 示例 ```python from collections import deque, defaultdict def topological_sort(graph): in_degree = defaultdict(int) adj_list = defaultdict(list) for node, neighbors in graph.items(): for neighbor in neighbors: in_degree[neighbor] += 1 adj_list[node].append(neighbor) queue = deque([node for node in graph if in_degree[node] == 0]) result = [] while queue: node = queue.popleft() result.append(node) for neighbor in adj_list[node]: in_degree[neighbor] -= 1 if in_degree[neighbor] == 0: queue.append(neighbor) return result if len(result) == len(graph) else False # 示例用法 graph = { 1: [2, 3], 2: [3], } print(topological_sort(graph)) ``` #### JavaScript 示例 ```javascript function topologicalSort(graph) { const inDegree = {}; const adjList = {}; for (const node in graph) { inDegree[node] = 0; adjList[node] = []; for (const neighbor of graph[node]) { inDegree[neighbor] = (inDegree[neighbor] || 0) + 1; adjList[node].push(neighbor); } } const queue = []; for (const node in inDegree) { if (inDegree[node] === 0) { queue.push(node); } } const result = []; while (queue.length > 0) { const node = queue.shift(); result.push(node); for (const neighbor of adjList[node]) { inDegree[neighbor]--; if (inDegree[neighbor] === 0) { queue.push(neighbor); } } } return result.length === Object.keys(graph).length ? result : false; } // 示例用法 const graph = { 1: [2, 3], 2: [3], }; console.log(topologicalSort(graph)); ``` **码小课网站中有更多相关内容分享给大家学习**,包括图论的其他算法、数据结构的应用等,欢迎访问学习。
推荐面试题