4

So, very recently, just out of curiosity, I bought the book 'Introduction to Algorithms' By CLRS. As I started going through the book, I noticed that some very typical algorithms in the book are implemented in very different way.

The implementation of quicksort given CLRS is much different than the popular Hoare's algorithm for quicksort.

So coming to my question...

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]);
            }
        }
    }
}

is the code used by Robert Sedgewick in his Coursera course on Algorithms.

In contrast, the insertion sort implementation given in CLRS is,

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;
    }
}

What's rather strange about this is the running time. Here are my results when I ran the two different implementations:

Number of elements in the array: 10,000

Time take by Robert Sedgewick's implementation: 0.235926s

Time take by CLRS's implementation: 0.078608s

Can somebody explain these results to me? The algorithm is pretty much the same. Only the implementation is different. How could a little difference in implementation cause such a huge difference in the running time?

Suyash Shetty
  • 513
  • 3
  • 8
  • 17

2 Answers2

3

The Robert Sedgewick code you show is primarily for illustration, not for performance.

Quoting from himself in his Algorithms book which uses the same code:

It is not difficult to speed up insertion sort substantially, by shortening its inner loop to move the larger entries to the right one position rather than doing full exchanges (thus cutting the number of array accesses in half). We leave this improvement for an exercise

Similar to his quicksort code in his Coursera course, see QuickSort Dijkstra 3-Way Partitioning: why the extra swapping?.

Community
  • 1
  • 1
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
2

The slight efficiency of the CLRS implementation that I see is that it does not swap the elements immediately but rather only copies the elements upwards and waits till the position of the key is obtained. It then copies the key in its correct position.

If at any iteration, the array is:

1 2 3 6 7 8 5
            ^

and the pointer is at 5, then in the first version, the steps would be:

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

whereas in the next version, the steps would be:

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
Abhishek Bansal
  • 12,589
  • 4
  • 31
  • 46