维基百科没有任何关于它的内容 谁知道呢?
我只想知道该算法的平均Big-O复杂度 the ? http://www.freeimagehosting.net/uploads/f18f22a095.jpg
答案 0 :(得分:5)
gnome排序算法的性能至少为O(f(n))
,其中f(n)
是输入列表中每个元素与该元素最终结束距离的总和。对于长度为L
的“随机”列表,列表开头的元素预计距离其排序位置的平均距离为L / 2
。列表中间的元素预计距离其排序位置的平均距离为L / 4
。由于总共L
个元素,f(n)
至少为L * L / 4
。因此,平均而言,gnome排序为O(n * n)
。
很抱歉,如果这很难理解。
答案 1 :(得分:1)
以下是对随机值数组的bubble和gnome排序,相反顺序的值,3个有序值和有序值的连接数组的简单比较。在比较方面,Gnome排序平均看起来要便宜一些。
请注意,排序随机值时的比较/交换总是有点不同,但接近这些结果。
N = 100,尝试= 1000
随机:
bubble sort:comparisons = 8791794,swaps = 2474088
gnome sort:comparisons = 5042930,swaps = 2474088
颠倒:
冒泡排序:比较= 9900000,交换= 4950000
gnome sort:比较= 9900000,交换= 4950000
3个有序集:
冒泡排序:比较= 6435000,交换= 1584000
gnome sort:比较= 3267000,交换= 1584000
有序:
冒泡排序:比较= 99000,交换= 0
gnome sort:comparisons = 99000,swaps = 0
...以下是用于获取这些结果的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const int N = 100;
int x[N];
int main()
{
srand((unsigned int)time(0));
int comparisons = 0;
int swaps = 0;
int attempts = 1000;
while (--attempts >= 0)
{
// random:
for (int i = 0; i < N; ++i)
x[i] = rand();
// reversed:
/*for (int i = 0; i < N; ++i)
x[i] = N - 1 - i;*/
// 3 ordered sets:
/*for (int i = 0; i < N/3; ++i)
x[i] = i;
for (int i = N/3, j = 0; i < 2*N/3; ++i, ++j)
x[i] = j;
for (int i = 2*N/3, j = 0; i < N; ++i, ++j)
x[i] = j;*/
// ordered:
/*for (int i = 0; i < N; ++i)
x[i] = i;*/
// bubble sort:
/*{
bool swapped;
do
{
swapped = false;
for (int i = 0; i < (N - 1); ++i)
{
++comparisons;
if (x[i] > x[i + 1])
{
++swaps;
int t = x[i];
x[i] = x[i + 1];
x[i + 1] = t;
swapped = true;
}
}
} while (swapped);
}*/
// gnome sort:
{
int i = 1;
while (i < N)
{
++comparisons;
if (x[i] >= x[i - 1])
++i;
else
{
++swaps;
int t = x[i];
x[i] = x[i - 1];
x[i - 1] = t;
if (i > 1)
--i;
}
}
}
}
printf("comparisons = %d\n", comparisons);
printf("swaps = %d\n", swaps);
}
显然这不是一个完整的测试,但它给出了一个想法。
答案 2 :(得分:0)
恰恰相反,维基百科说它是O(n 2 ),从描述中,我看不出对此有什么真正的怀疑。
答案 3 :(得分:0)
如果不查看输入数据,“平均”无法真正回答。如果您知道自己要排序的内容,可以进行一些分析,以便更好地了解它在您的应用程序中的表现。
答案 4 :(得分:0)
对我来说,如果插入排序的平均运行时间为O(n ^ 2),并且gnome sort是插入排序的稍差版本,那么gnome sort的平均运行时间也将是O,这似乎很直观。 (n ^ 2)(嗯,Θ(n ^ 2))。
This pdf有关于插入排序的平均案例运行时间Θ(n ^ 2)的说法:
证明这一点并非无足轻重,但是 它基于直观的事实 平均而言,while循环测试 “list [pos-1]&gt; value”是真实的 一半的时间,所以平均来说, while循环的执行次数 是最大数量的一半。 由于最大数量是n(n-1)/ 2, 平均执行次数 while循环是n(n-1)/ 4,即 仍然Θ(n ^ 2)。
同样的推理适用于gnome排序。你知道gnome排序不可能更好,因为“gnome”首先必须向后扫描(通过交换)以找到项目所在的位置(相当于插入排序的向前扫描),然后必须向上走回列表查看元素它已经排序了。我认为扫描方法之间的任何运行时差异都可以忽略不计复杂性,但我会按照你的要求来证明它。
答案 5 :(得分:-1)
维基百科明确表示,其最坏情况下的运行时间为O(n ** 2)。
答案 6 :(得分:-1)
http://en.wikipedia.org/wiki/Gnome_sort
这是O(n^2)
。最糟糕的情况是,每当你输入当前位置需要与之前的位置交换时,这会使pos变小,你必须再次交换。在后代排序数组上测试升序排序(即从[4 3 2 1]得到[1 2 3 4]你得到最坏的情况)。