Algorithm Implementation/Sorting/Gnome sort

C

void gnome_sort(int *array, int size){ 
   int i, tmp; 
   for(i=1; i<size; ){
       if(array[i-1] <= array[i])
           ++i;
       else{
           tmp = array[i];
           array[i] = array[i-1];
           array[i-1] = tmp;
           --i;
           if(i == 0)
               i = 1;
       }
   }
}
↑Jump back a section

C++

#include <algorithm> // for std::swap
void gnomeSort( int *array, int size )
  {
   for ( int i = 1; i < size; ) {
     if ( array[i-1] <= array[i] ) {
       ++i;
     }
     else {
       std::swap( array[i-1], array[i] );
       --i;
       if ( i == 0 ) {
         i = 1;
       }
     }
   }
}

C++ using bidirectional iterators

#include <algorithm> // for std::iter_swap
 
template <typename Iterator>
void gnome_sort(Iterator begin, Iterator end)
{
    Iterator current = begin;
    Iterator before_current;
 
    while (current != end)
    {
        if (current == begin || *before_current <= *current)
        {
            ++current;
        }
        else
        {
            std::iter_swap(before_current, current);
            --current;
        }
        before_current = current;
        --before_current;
    }
}

Optimized C++ using iterators

#include <algorithm> // for std::iter_swap
#include <iterator> // for std::advance
 
template <typename Iterator>
void gnome_sort(Iterator begin, Iterator end)
{
    Iterator current = begin;
    Iterator before_current;
    size_t step = 1;
 
    while (current != end)
    {
        if (current == begin || *before_current <= *current)
        {
            std::advance(current, step); // possible leap optimization
            step = 1;
        }
        else
        {
            std::iter_swap(before_current, current);
            --current;
            ++step;
        }
        before_current = current;
        --before_current;
    }
}

The optimized version makes the "gnome" (represented by the 'current' iterator here) leap back to the right i.e. to the place where it needed to swap the flower pots on its farthest reached position so far. This also avoids redundant comparisons. On average the optimization results in cutting the time by one/third on a modern x86 machine. (A wise gnome sort? :). However, the optimization works best if the iterators are random access iterators. Otherwise the algorithm works almost like the non-optimized version - it still avoids redundant comparisons though.

↑Jump back a section

C#

void GnomeSort( int[] array ) 
{ 
  for ( int i = 1, temp_value; i < array.Length; ) 
  { 
    if ( array[i-1] <= array[i] ) 
      i += 1; 
    else 
    { 
      temp_value = array[i-1]; 
      array[i-1] = array[i]; 
      array[i] = temp_value; 
      i -= 1; 
      if ( i == 0 ) 
        i = 1; 
    } 
  } 
}
↑Jump back a section

FORTRAN

SUBROUTINE gnome_sort(LIST, LENGTH) 
INTEGER LIST, LENGTH, I, TEMP 
DIMENSION LIST(LENGTH) 
I = 2 
WHILE (I .LE. LENGTH) DO 
  IF ((I .EQ. 1) .OR. (LIST(I-1) .LE. LIST(I))) THEN 
    I = I + 1 
  ELSE 
    TEMP = LIST(I) 
    LIST(I) = LIST(I-1) 
    LIST(I-1) = TEMP 
    I = I - 1 
    IF (I .EQ. 1) THEN 
      I = 2 
    END IF 
  END IF 
END WHILE 
END
↑Jump back a section

Java

public class GnomeSort { 
   static void gnomeSort( int[] theArray ) { 
      for ( int index = 1; index < theArray.length; ) { 
         if ( theArray[index - 1] <= theArray[index] ) { 
            ++index; 
         } else { 
            int tempVal = theArray[index]; 
            theArray[index] = theArray[index - 1]; 
            theArray[index - 1] = tempVal; 
            --index; 
            if ( index == 0 ) { 
               index = 1; 
            }           
         } 
      } 
   } 
}
↑Jump back a section

JavaScript

function gnomeSort(sortMe) {
   i=0;
   while (i < sortMe.length) {
      if (i==0||sortMe[i-1] <= sortMe[i]) {
         i++;
      } else {
         tmp=sortMe[i];
         sortMe[i]=sortMe[i-1];
         sortMe[--i]=tmp;
      }
   }
}
↑Jump back a section

LavishScript

This sorts an scope-accessible index:objectype (IndexName) passed by variable name, sorting by MemberName, which should be a numeric member of objecttype.

method Gnomesort(string IndexName, string MemberName)
{
  variable int i = 1
 
  while ${i} <= ${${IndexName}.Used}
  {
    if ( ${i} == 1 ) || ${${IndexName}[${Math.Calc[${i}-1]}].${MemberName}} <= ${${IndexName}[${i}].${MemberName}}
    {
      i:Inc
    }
    else
    {
      ${IndexName}:Swap[${i}, ${Math.Calc[${i}-1]}]
      i:Dec
    }
  }
}
↑Jump back a section

Perl

sub gnome_sort(@) 
{ 
  my @a = @_; 
  my $i = 1; 
  while ($i < @a) { 
    if ($a[$i-1] <= $a[$i]) { 
      $i++; 
    } 
    else { 
      @a[$i-1, $i] = @a[$i, $i-1]; 
      $i--; 
      $i = 1 if $i == 0; 
    } 
  } 
  return @a; 
}
↑Jump back a section

PHP

<?php 
function gnome_sort($list) 
{ 
    for ($i = 1; $i < count($list);) 
    { 
        if ($list[$i-1] <= $list[$i]) {$i++;} 
        else 
        { 
            $temp = $list[$i]; 
            $list[$i] = $list[$i-1]; 
            $list[$i-1] = $temp; 
            $i--; 
            if ($i == 0) {$i = 1;} 
        } 
    } 
    return $list; 
}
?>
↑Jump back a section

Python

def gnomeSort(items):
    i = 0
    n = len(items)
    while i < n:
        if i and items[i] < items[i-1]:
            items[i], items[i-1] = items[i-1], items[i]
            i -= 1
        else:
            i += 1
    return
 
 
def teleportingGnomeSort(items):
    i = j = 0
    n = len(items)
    while i < n:
        if i and items[i] < items[i-1]:
            items[i], items[i-1] = items[i-1], items[i]
            i -= 1
        else:
            if i < j: # teleport!
                i = j
            j = i = i+1
    return
↑Jump back a section

Ruby

module GnomeSort
  def self.sort(keys)
    sort!(keys.clone)
  end
 
  def self.sort!(keys)
    i, j = 1, 2
    while i < keys.size
      if keys[i-1] <= keys[i]
        i, j = j, j+1
      else
        keys[i-1], keys[i] = keys[i], keys[i-1]
        i -= 1 if i > 1
      end
    end
    keys
  end
end
↑Jump back a section

Read in another language

This page is available in 1 language

Last modified on 15 October 2011, at 07:50