所以我知道这个算法非常简单,但我无法解决代码的时间复杂性问题。它接收一个数组(比如5个数字)并按递增顺序排序,并以类似于冒泡排序的方式排序(但不完全相同)。此算法的最佳和最差情况运行时间是什么?
int sort(int arr[1...n]){
while(i <= n){
k = n;
while(k >= i+1){
if (arr[k-1] > arr[k]){
tmp = arr[k-1];
arr[k-1] = arr[k];
arr[k] = tmp;
}
k--;
}
i++;
}
}
我的推理:
最坏情况将是数组处于反向排序顺序,例如[5,4,3,2,1]。我知道外部while循环会被执行n次,但内部while循环会让我失望。对于外部while的每次迭代,我认为内部while执行i + 1次,所以对于我给出的数组,它将执行内部而4,3,2,然后最后1次(这是总共(n) -1)内部while循环的执行)...把它放在一起我有n *(n-1),所以这意味着最坏的情况是O(n ^ 2)?
最佳情况是数组已经排序的时候,比如[1,2,3,4,5]。所以在这种情况下,我们永远不需要进行数字交换,并且永远不会执行内部while中的if语句。但是代码似乎遍历了所有内容,尽管数组已经排序了。我们仍然经历了两个while循环,这让我相信它仍然是n *(n-1),但这似乎不适合我。任何帮助表示赞赏。
答案 0 :(得分:1)
在最坏的情况下,将有1 + 2 + 3 + ...(n-1)次迭代,因此n(n-1)/2
=&gt; n^2/2 - n/2
。
忽略常数,该算法具有最差O(n^2 - n)
复杂度,仅为O(n^2)
。
答案 1 :(得分:0)
即使阵列已经排序,代码“遍历所有内容”也就不足为奇了。你不要告诉它。
您需要添加一个sentinel值,告诉它在数组已经排序时停止。
在您的代码中,如果在单次传递期间从未输入内部if
语句,那么您就知道该数组已排序。所以你要做的是在外循环的每次迭代开始时初始化一个标志。如果输入if
语句,则设置标志。如果,该标志未在out循环迭代结束时设置,那么您就知道该数组已排序。这是代码:
int sort(int arr[1...n]){
bool didSwap = true;
while(i <= n && didSwap){
didSwap = false;
k = n;
while(k >= i+1){
if (arr[k-1] > arr[k]){
tmp = arr[k-1];
arr[k-1] = arr[k];
arr[k] = tmp;
didSwap = true;
}
k--;
}
i++;
}
}
这将使您的代码在数组排序时“提前”。