Kruskal算法时间复杂度证明两大疑问:边数上限为何小于节点数平方?排序时间为何可简化为mlogn?
解析Kruskal算法时间复杂度的两个关键疑问
嘿,我来帮你理清这两个关于Kruskal算法时间复杂度的困惑,咱们一步步拆解:
1. 为什么边的最大数量小于节点数的平方?
咱们算法分析里默认讨论的是简单图(没有自环、没有重复边的图,毕竟自环在最小生成树里完全没用,不会被纳入考虑):
- 无向图的话,每条边连接两个不同节点,最多有
C(n,2) = n(n-1)/2条边。这个值显然小于n²——毕竟n(n-1)/2 = (n² -n)/2,比n²少了近一半的量,肯定达不到n²。 - 有向图的话,每条边是从一个节点指向另一个不同节点,最多有
n(n-1)条边,同样小于n²(因为n(n-1) = n² -n,比n²少了n条边)。
就算退一步考虑允许自环的图,最多也就 n² 条边,但这种场景在最小生成树问题里几乎不会出现,所以实际分析中,边的最大数量必然小于节点数的平方。
2. 为什么排序边的时间复杂度可以从mlogm推导为mlogn?
这里的核心是大O时间复杂度的等价性,咱们用数学推导和实例来理解:
首先,我们已经知道在简单图里 m ≤ n²,对两边取对数(不管底数是多少,大O分析里不影响结果):logm ≤ log(n²) = 2logn
把这个代入排序的时间复杂度 mlogm 里,就得到:mlogm ≤ m * 2logn
而大O符号的规则是忽略常数因子,所以 O(mlogm) = O(m*2logn) = O(mlogn)——两者的时间复杂度是同阶的。
举个完全图的例子更直观:当 m = n(n-1)/2 ≈ n²/2 时,logm = log(n²/2) = 2logn - log2,这时候 mlogm = (n²/2)(2logn - log2) = n²logn - (n²/2)log2,而 mlogn = (n²/2)logn。你看,两者的最高阶项都是 n²logn,低阶项和常数在大O分析里都可以忽略,所以它们的时间复杂度是等价的。
《Algorithm Design》里说“排序边的时间复杂度至多为mlogn”,其实是在用节点数n来表述这个上界,这样更贴合我们用节点数衡量算法复杂度的习惯,本质上和mlogm是同一个复杂度阶。
内容的提问来源于stack exchange,提问作者lyj




