Gnome排序的平均Big-0复杂度是多少?

时间:2010-01-14 18:30:19

标签: algorithm sorting complexity-theory

维基百科没有任何关于它的内容 谁知道呢?

我只想知道该算法的平均Big-O复杂度 the ? http://www.freeimagehosting.net/uploads/f18f22a095.jpg

7 个答案:

答案 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]你得到最坏的情况)。