[英]Issue regarding time complexity in Kahn's BFS algo for topological sort
到处都写着用于拓扑排序的 Kahn 的 BFS 算法需要 O(V+E) 时间复杂度,但是如果我分解它的代码,我意识到在计算顶点的入度时,我们正在多次访问一个顶点,所以不应该TC 是 O(n^2) 吗? 同样在我们的 while 循环中,我们不止一次访问顶点,那么 TC 怎么仍然是 O(V+E) ?
这是我的代码:
public static void sort(ArrayList<ArrayList<Integer>> adjList,int vertices){
int[] inDegree=new int[vertices];
for(int i=0;i<adjList.size();i++){
for(int element : adjList.get(i)){
inDegree[element]++;
}
}
Queue<Integer> ourQueue=new LinkedList<>();
for(int i=0;i<vertices;i++){
if(inDegree[i]==0){
ourQueue.add(i);
}
}
while(!ourQueue.isEmpty()){
int poppedElement=ourQueue.poll();
System.out.print(poppedElement+" ");
for(int element : adjList.get(poppedElement)){
inDegree[element]--;
if(inDegree[element]==0){
ourQueue.add(element);
}
}
}
}
在大多数图表中, |E|
>> |V|
. 让我们使用|E| = m
|E| = m
和|V| = n
|V| = n
。 在连通图中,您将拥有m >= n-1
; 在完整的图表中,您将拥有m = n*(n-1)
。 因此,对于m
介于这些极端之间的“平均”图, O(m+n)
看起来与O(m)
和O(n*n)
非常相似。
在您的实现中,您使用的是具有n*n
单元的邻接矩阵; 简单地填充该矩阵已经是O(n*n)
- 在第一个循环中执行的顶点度数计算也是如此。 如果您使用的是邻接列表,则不需要循环(顶点度数可以计算为每个顶点的邻接列表的长度,如果使用 ArrayList ,则为 O(1))。 因此,实现肯定会影响运行时最坏情况的复杂性。
您评论说,一个在线编程拼图网站将您的代码列为O(V+E)
。 然而,找出一段代码复杂性的唯一实用方法(没有人工或非常复杂的自动分析,在一般情况下注定会失败)是用一组不断增加的输入来运行它。 正如我在上面所说的, O(V+E)
和O(V*V)
之间的差异可能相对较小。
简而言之:
m
接近n*n
,并且O(V+E)
、 O(E)
和O(V*V)
之间没有显着差异。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.