【问题标题】:Difference in running time of insertion sort using CLRS's code and Robert Sedgewick's code使用 CLRS 的代码和 Robert Sedgewick 的代码进行插入排序的运行时间差异
【发布时间】:2014-12-15 01:46:56
【问题描述】:

所以,最近,出于好奇,我买了 CLRS 的《算法简介》一书。当我开始阅读本书时,我注意到书中一些非常典型的算法以非常不同的方式实现。

给定 CLRS 的快速排序实现与流行的快速排序 Hoare 算法有很大不同。

所以来回答我的问题...

void insertion_sort_by_robertsedgewick(int a[],int n)
{   
    for(int i=0;i<n;i++)
    {
        for(int j=i;j>0;j--)
        {
            if(a[j]<a[j-1])
            {
                swap(a[j],a[j-1]);
            }
        }
    }
}

是 Robert Sedgewick 在他的 Coursera 算法课程中使用的代码。

相比之下,CLRS中给出的插入排序实现是,

void insertion_sort_CLRS(int a[] , int n)
{
    int key,j;
    for(int i=1; i<n; i++)
    {
        key = a[i];
        j = i - 1;
        while(j>=0 && a[j]>key)
        {
            a[j+1] = a[j];
            j--;
        }
        a[j+1] = key;
    }
}

比较奇怪的是运行时间。 以下是我运行两种不同实现时的结果:

数组元素个数:10,000

Robert Sedgewick 的实现耗时:0.235926s

CLRS 的实现耗时:0.078608s

有人可以向我解释这些结果吗? 该算法几乎相同。只是实现方式不同。实现上的一点点差异怎么会导致运行时间的巨大差异?

【问题讨论】:

    标签: performance algorithm sorting insertion-sort clrs


    【解决方案1】:

    您展示的 Robert Sedgewick 代码主要用于说明,而不是用于性能。

    在他使用相同代码的算法书中引用他自己的话:

    通过缩短其内部循环将较大的条目向右移动一个位置而不是进行完全交换(因此 将数组访问次数减半)。我们将此改进留作练习

    类似于他在 Coursera 课程中的快速排序代码,请参阅 QuickSort Dijkstra 3-Way Partitioning: why the extra swapping?

    【讨论】:

      【解决方案2】:

      我看到的 CLRS 实现的轻微效率是它不会立即交换元素,而只是向上复制元素并等待直到获得键的位置。然后它将密钥复制到正确的位置。

      如果在任何迭代中,数组是:

      1 2 3 6 7 8 5
                  ^
      

      指针在5,那么在第一个版本中,步骤是:

      1 2 3 6 7 5 8
      1 2 3 6 5 7 8
      1 2 3 5 6 7 8
      

      而在下一个版本中,步骤将是:

      1 2 3 6 7 8 8
      1 2 3 6 7 7 8
      1 2 3 6 6 7 8
      1 2 3 5 6 7 8
      

      【讨论】:

        猜你喜欢
        • 2016-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-26
        • 2019-09-11
        • 1970-01-01
        相关资源
        最近更新 更多