23

I'm looking for a sorting algorithm for int arrays that doesn't allocate any byte other than the size of the array, and is limited to two instructions:

  1. SWAP: swap the next index with the current one;

  2. MOVE: moves the cursor to +1 or -1 index;

That is, you can't swap non neighboring indexes, nor swap the index 100, after you just swapped index 10. What is the most efficient algorithm - i.e., the one that uses the less amount of total moves?

Raphael
  • 73,212
  • 30
  • 182
  • 400
MaiaVictor
  • 4,199
  • 2
  • 18
  • 34

3 Answers3

15

Consider cocktail shaker sort, which is a bidirectional version of bubble sort. You bubblesort from low to high, and then (this is the added part) you bubblesort from high to low, repeat until done. This is still $O(n^2)$, but it makes significantly fewer passes on average, because small elements near the high end of the array will be moved to their final position in a single pass rather than N passes. Also, you can keep track of the lowest and highest positions where a swap occurred; subsequent passes need not scan beyond those points.

zwol
  • 297
  • 1
  • 7
4

The only algorithm with the two operators that you have mentioned which is quite efficient is the bubble sort. The complexity of the algorithm is $O(n^2)$ in the worst case.

I also assume apart from the two operations, we can also check whether we are at the rightmost (Op 3) or leftmost position (Op 4), either by use of sentinels $-\infty$ and $+\infty$ or by some operation on the list. Also we should have a comparison operation (Op 5) given separately or combined with swap operation. If the comparison operation is combined with the swap operation then it must tell us whether the swap was performed or not.

The algorithm that does not uses a boolean flag to know whether we have swapped any element or not, is given below (the trick to keep the information in the state of the machine, rather than memory):

Start:
    Do until we are not at the leftmost position (Op 4)
        move left (Op 2b)

Check:
    If we are at rightmost position (Op 3)
        goto Finished:
    If current value is larger than next value (Op 5)
        goto Unfinished:
    move right (Op 2a)
    Repeat Check:

Unfinished:
    If we are at rightmost position (Op 3)
        goto Start:
    If current value is larger than next value (Op 5)
        swap the elements (Op 1) and move right (Op 2a)
    Repeat Unfinished:

Finished:
    The list is sorted now, output it.

The solution of Eric Lippert, the gnome sort also works, because basically it is a two way bubble sort.

Sarvottamananda
  • 4,877
  • 1
  • 14
  • 19
4

The number of swaps of adjacent elements needed to order an array is equal to the number of inversions in the array. With n elements in total, there are at most n*(n-1)/2 inversions, so bubble sort gives the asymptotically optimal number of swaps in this model.

Charles
  • 256
  • 1
  • 5