据我了解,算法的复杂性是排序时执行的最大操作次数。因此,冒泡排序的复杂性应该是算术级数(从1到n-1)的总和,而不是n ^ 2。 以下实现计算比较次数:
public int[] sort(int[] a) {
int operationsCount = 0;
for (int i = 0; i < a.length; i++) {
for(int j = i + 1; j < a.length; j++) {
operationsCount++;
if (a[i] > a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
System.out.println(operationsCount);
return a;
}
具有10个元素的数组的输出为45,因此它是从1到9的算术级数之和。
那么为什么冒号排序的复杂性是n ^ 2,而不是S(n-1)?
答案 0 :(得分:6)
这是因为big-O表示法描述了算法的性质。扩展(n-1) * (n-2) / 2
中的主要术语是n^2
。因此,n
增加所有其他术语变得微不足道。
欢迎您更准确地描述它,但是出于所有意图和目的,该算法展示了行为,其顺序为n^2
。这意味着如果您将时间复杂度与n
进行对比,您将看到抛物线增长曲线。
答案 1 :(得分:0)
让我们做最坏的案例分析。
在最坏的情况下,if (a[i] > a[j])
测试将始终为true,因此接下来的3行代码将在每个循环步骤中执行。内部循环从j = i + 1变为n-1,因此它将执行Sum_{j=i+1}^{n-1}{k}
个基本操作(其中k是涉及创建temp
变量的常量操作数,数组索引和价值复制)。如果求解求和,则会给出一些等于k(n-i-1)
的基本运算。外部循环将重复此k(n-i-1)
基本操作,从i = 0到i = n-1(即Sum_{i=0}^{n-1}{k(n-i-1)}
)。因此,再次,如果您求解求和,您会看到最终的基本运算数与n ^ 2成正比。在最坏的情况下,算法是二次的。
当你在内循环中运行任何代码之前递增变量operationsCount
时,我们可以说在我们之前的分析中k(在内循环内执行的基本操作的数量)是1.所以,求解Sum_{i=0}^{n-1}{n-i-1}
给出n^2/2 - n/2
,用10代替n给出45的最终结果,与运行代码得到的结果相同。