tags:

views:

321

answers:

7

The following algorithm can sort three variables x, y and z of type K which are comparable using operator<:

void sort2(K& x, K& y) {
   if(y < x)
      swap(x, y);
}      

void sort3(K& x, K& y, K& z) {
   sort2(x, y);
   sort2(y, z);
   sort2(x, y);
}

This needs three swaps in the "worst case". However basic mathematics tells us, that the ordering of three values can be done using only two swaps.

Example: The values (c,b,a) will be sorted using three swaps: (c,b,a) -> (b,c,a) -> (b,a,c) -> (a,b,c). However one swap would have been enough: (c,b,a) -> (a,b,c).

What would be the simplest algorithms which sorts three variables with at most two swaps in all cases?

+16  A: 

Find the smallest, this takes 2 comparisons, and swap it into the first position. Then compare the remaining 2 and swap if necessary.

if (x < y) {
   if (z < x) swap(x,z);
} else {
  if (y < z) swap(x,y);
  else swap(x,z);
} 
if(z<y) swap(y,z);

This takes up to 3 comparisons, but only two swaps.

deinst
The last line must be `if(z<y) swap(y,z);`.
Danvil
Doh! It is now fixed. Thanks
deinst
This is perhaps not the "simplest algorithms" - but it is the only one suggested.
Danvil
+5  A: 

Find the minimum value and swap it with the first value. Find the second minimum and swap it with the second value. Two swaps at most.

This is basically selection sort, which will perform at most n - 1 swaps.

IVlad
A: 

Encode a sorting network in a table. The Wikipedia article I linked should help you with references in case you need to figure out what to put in the table in other cases (i.e., bigger arrays).

+1  A: 

I think what you want is to find the optimal swap in each step instead of just a valid swap. To do that, just find the greatest difference between an element and an element later in the list and swap those. In a 3-tuple, there are three possible swaps, 1-3, 1-2, and 2-3. At each step find the max difference among these three swaps and do that. Pretty sure that gives two swaps in the worst case for 3 elements. Only really makes sense if swapping is relatively expensive compared to comparing elements, otherwise probably not worth the additional analysis upfront.

bshields
+2  A: 

If you don't do it in place, you can perform it without any swaps.

Gary
Still you have to swap the pointers.
Danvil
no, you can just put them in the right place in the new array to begin with :-), just nit-picking, it's equivalent to a swap, but not really a swap.
Gary
Correct, I thought of something else ;)
Danvil
+1  A: 

I always like http://www.sorting-algorithms.com/, the animations help me see how the algorithms work.

JLWarlow
This is funny indeed! But does not solve the problem ...
Danvil
The link also contains code and orders; it doesn't say for a given problem use this algorithm though which would be nice.
JLWarlow
+1  A: 

Cool question :)

If assembly is available to you, and the values fit in a register, then you can probably do it extremely fast by just loading them into registers and doing a few compares, jumping to the right scenario to put the values back. Maybe your compiler makes this optimization already.

Either way, if performance is your goal, take a look at the generated machine code and optimize there. For such a small algorithm that's where you can squeeze performance out of.

tenfour
Any code for this? My assembler skills are at best negligible ...
Danvil