Sorting algorithms/Quicksort: Difference between revisions

From Rosetta Code
Content added Content deleted
(add Forth)
Line 35: Line 35:
: exch ( addr1 addr2 -- ) dup @ >r over @ swap ! r> swap ! ;
: exch ( addr1 addr2 -- ) dup @ >r over @ swap ! r> swap ! ;
: part ( l r -- l r r2 l2 )
: partition ( l r -- l r r2 l2 )
2dup mid @ >r ( r: pivot )
2dup mid @ >r ( r: pivot )
2dup begin
2dup begin
Line 44: Line 44:
: qsort ( l r -- )
: qsort ( l r -- )
part swap rot
partition swap rot
\ 2over 2over - + < if 2swap then
\ 2over 2over - + < if 2swap then
2dup < if recurse else 2drop then
2dup < if recurse else 2drop then

Revision as of 02:48, 4 October 2007

Task
Sorting algorithms/Quicksort
You are encouraged to solve this task according to the task description, using any language you may know.

In this task, the goal is to sort an array of elements using the Quicksort algorithm. The elements must have a total order and the index of the array can be of any discrete type. For languages where this is not possible, sort an array of integers.

C

void quick(int *left, int *right)
{
  if (right > left) {
    int pivot = left[(right-left)/2];
    int *r = right, *l = left;
    do {
      while (*l < pivot) l++;
      while (*r > pivot) r--;
      if (l <= r) {
        int t = *l;
        *l++ = *r;
        *r-- = t;
      }
    } while (l <= r);
    quick(left, r);
    quick(l, right);
  }
}
void sort(int *array, int length)
{
  quick(array, array+length-1);
}

Forth

defer lessthan ( a@ b@ -- ? )   ' < is lessthan

: mid ( l r -- mid ) over - 2/ -cell and + ;

: exch ( addr1 addr2 -- ) dup @ >r over @ swap ! r> swap ! ;

: partition ( l r -- l r r2 l2 )
  2dup mid @ >r ( r: pivot )
  2dup begin
    swap begin dup @  r@ lessthan while cell+ repeat
    swap begin r@ over @ lessthan while cell- repeat
    2dup <= if 2dup exch >r cell+ r> cell- then
  2dup > until  r> drop ;

: qsort ( l r -- )
  partition  swap rot
  \ 2over 2over - + < if 2swap then
  2dup < if recurse else 2drop then
  2dup < if recurse else 2drop then ;

: sort ( array len -- )
  dup 2 < if 2drop exit then
  1- cells over + qsort ;

IDL

IDL has a powerful optimized sort() built-in. The following is thus merely for demonstration.

function qs, arr
  if (count = n_elements(arr)) lt 2 then return,arr
  pivot = total(arr) / count ; use the average for want of a better choice
  return,[qs(arr[where(arr le pivot)]),qs(arr[where(arr gt pivot)])]
 end

Example:

IDL> print,qs([3,17,-5,12,99])
     -5       3      12      17      99