我相信BubbleSort的顺序为O(n ^ 2)。在我阅读之前的帖子时,这与嵌套迭代有关。但是,当我运行一个简单的未排序列表(见下文)时,我将列表排序为10个比较。
在我的示例中,这是我的整数值列表: 5 4 3 2 1
为了获得5个位置,我进行了n-1次交换操作。 (4)
为了获得4个位置,我进行了n-2次交换操作。 (3)
为了获得3个位置,我进行了n-3交换操作。 (2)
为了获得2个位置,我进行了n-4交换操作。 (1)
我无法看到(n ^ 2)来自哪里,因为当我有一个n = 5项的列表时,我只需要10次交换操作。
顺便说一句,我已经看过(n-1)。(n-1)这对我没有意义,因为这会给出16次交换操作。我只关心基本的BubbleSort ...一个简单的嵌套FOR循环,为了简单和清晰。
答案 0 :(得分:4)
你似乎并不理解big O notation的概念 好。它指的是操作次数或时间的增长方式 与输入大小的关系,渐近,仅考虑 增长最快的术语,而不考虑常数 比例
像5:10结果这样的单一测量完全没有意义。 想象一下,寻找一个映射5到10的函数。它是2N吗? N + 5? 4N - 10? 0.4N 2 ? N 2 - 15? 4 log 5 N + 6?该 可能性是无限的。
相反,你必须分析算法,看看数量如何 操作按N增长,或测量操作或时间超过许多 运行,使用N的各种值和最常用的数据集 设计。请注意,您的测试用例根本不是通用的:检查时 排序算法的平均性能,您希望输入 以随机顺序(最可能的情况),未排序或反向排序。答案 1 :(得分:1)
如果您想精确地进行(n)*(n-1)/2
操作,因为您实际上正在计算n+(n-1)+(n-2)+...+1
,因为第一个元素需要n
交换,第二个元素需要n-1
交换等等。因此该算法为O(1/2 * (n^2) - n)
,其渐近符号等于O(n^2)
。但实际上在泡沫排序中发生的事情是不同的。在冒泡排序中,您执行数组传递并交换错位的邻居位置,直到没有错位,这意味着数组已经排序。由于每次传递数组都需要O(n)
次,而在最坏的情况下,您必须执行n
次传递,因此算法为O(n^2)
。请注意,我们计算的是比较次数而不是掉期次数。
维基百科中提到了两种版本的冒泡排序:
procedure bubbleSort( A : list of sortable items )
n = length(A)
repeat
swapped = false
for i = 1 to n-1 inclusive do
/* if this pair is out of order */
if A[i-1] > A[i] then
/* swap them and remember something changed */
swap( A[i-1], A[i] )
swapped = true
end if
end for
until not swapped
end procedure
此版本执行(n-1)*(n-1)
比较 - > O(n^2)
优化冒泡排序
冒泡排序算法很容易 通过观察第n次通过找到第n个最大值来优化 元素并将其置于最终位置。所以,内循环可以避免 在第n次跑步时查看最后的n-1项:
procedure bubbleSort( A : list of sortable items )
n = length(A)
repeat
swapped = false
for i = 1 to n-1 inclusive do
if A[i-1] > A[i] then
swap(A[i-1], A[i])
swapped = true
end if
end for
n = n - 1
until not swapped
end procedure
此版本执行(n-1)+(n-2)+(n-3)+...+1
次操作,(n-1)(n-2)/2
比较 - > O(n^2)