我的算法课程中出现了以下应用/理论问题,我的教授和TA都得到了相互矛盾的答案。
在(a)最坏的情况下,对数组进行起泡需要多少次比较? (b)最好的情况?
我知道标准的bubblesort算法是
for i = 0 to n - 2
for j = n - 1 to i + 1
if A[j - 1] > A[j]
swap(A[j - 1], A[j])
我实际上用Google搜索了这个问题,问题的答案实际上分别是300
和24
。但我对这里的“比较”一词感到困惑。我们考虑比较什么?我们是否只考虑if
检查本身,或者它执行的代码块是否为真?在最坏的情况下,swap和if
语句将执行总共n(n-1)/2
次。但是,在最好的情况下,if
语句将像之前一样检查有效性n(n-1)/2
次,但由于数组在最佳情况下排序,因此不会发生交换。这意味着对于最坏情况和最佳情况,比较次数是否相同,不是吗?
我的教授说“比较”的意思是“比较两个要素”,但没有解释得多。我的TA认为它可能基于for
循环的执行次数。
它让我更加困惑:在算法的这个定义中,我们如何从最好的情况中提取出呢?{1}}?显然,在最好的情况下,不会发生交换,但内部循环将在外部for循环中为O(n)
的每个值运行,因此算法将经历数组i
次。这里只有n(n-1)/2
次提供给我们n-1
?
我找到的原始问题的答案使用优化的bubblesort算法,该算法仅使用1个for循环,如果没有发生交换则退出。这是一个更好的算法用于问题吗?即,
O(n)
在这种特殊情况下,它的所有来源都非常明显。但是讲座和我们的书中的算法从未提到过这一点。
感谢阅读!
答案 0 :(得分:1)
我们考虑比较什么?
if
语句是比较。它是该代码段中唯一正在测试任何内容的代码。
这意味着对于最坏情况和最佳情况,比较次数是否相同,不是吗?
使用该代码段,是的。
我们如何根据算法的定义从最佳情况中提取出的冒号是
O(n)
?
根据之前的回答,这不是。
跳到上一个问题(因为它回答了剩下的问题):
我找到的原始问题的答案使用优化的bubblesort算法,该算法仅使用1个for循环,如果没有发生交换则退出。这是一个更好的算法用于问题吗?
它可能更复杂,取决于它的编写方式,但在优化比较次数方面,它会更好。
答案 1 :(得分:1)
你是正确的,使用这个精确的伪代码,所做的比较次数总是相同的,因为代码每次都进行相同的比较。请注意,此代码不执行冒泡排序通常执行的操作,只要在没有交换发生的情况下进行通过就会突破循环,因此实际上不会在时间O中运行(n)在最好的情况下。此代码总是需要时间Θ(n 2 )。事实上,我不会真正称之为代码冒泡,正是出于这个原因。
如果更新代码以便在未对基础数组进行任何更改时突破外部循环,那么您将开始获得更多有趣的模式和行为。这就是你获得O(n)最佳案例运行时,在最佳情况下进行24次比较等等。
答案 2 :(得分:1)
我们考虑比较什么?我们是否只考虑if检查本身,或者它执行的代码块是否为真?
只需if
支票。但是,你认为最坏情况下的掉期数是完全相同的。
我们如何根据算法的定义从最佳情况中提取出Bubbleort是O(n)?
你是绝对正确的,在最好的情况下你使用的实现不 O(n)。当内循环中没有交换时,您需要进行小优化以使其停止:
bool done = false
while (!done)
done = true
for j = n - 1 to i + 1
if A[j - 1] > A[j]
swap(A[j - 1], A[j])
done = false
这样一旦内循环中没有完成交换,外循环就会停止。在最好的情况下,内部循环的第一次迭代也将是最后一次迭代,产生预期的O(n)次比较。
答案 3 :(得分:1)
for i = 0 to n - 2
for j = n - 1 to i + 1
if A[j - 1] > A[j]
swap(A[j - 1], A[j])
正如您所建议的那样,正在进行的比较是第三行。我认为这有意义的部分是我们正在比较A的两个要素和另一个要素。 A [j-1]和A [j]。我们在这里做的具体比较比比较大。 (X1> X2?)我们正在研究两个元素并确定它们之间的关系。
我实际上用Google搜索了这个问题,问题的答案实际上分别是300和24。
对于n的特定值,这将是真实的,而不是对于n的所有情况。 n是数组中元素的数量,当我们谈论时间复杂性时,它们通常是指我们正在看的集合的大小。