Bubble sort

algoritmo di ordinamento di una lista di dati
Versione del 21 lug 2005 alle 09:02 di Bermas66 (discussione | contributi) (ho messo i cicli in forma tradizionale (peraltro c'era anche un errore!))

Il Bubble Sort, in italiano ordinamento a bolla, è un semplice algoritmo per ordinare gli elementi di un array.

L'algoritmo comincia con un ciclo in cui ogni elemento, a partire dall'ultimo, è confrontato con l'elemento che lo precede; se i due elementi non si trovano nell'ordine esatto vengono scambiati. Alla fine del primo ciclo inevitabilmente l'elemento 'più leggero' come una bolla sarà risalito in prima posizione. Il secondo ciclo esegue le stesse operazioni escudendo il primo elemento e così facendo risalire il secondo elemento 'più leggero' e così si prosegue fino all'orinamento completo. Se N è la lunghezza del array, occorreranno N-1 di questi cicli. E' anche possibile invertire l'ordine delle operazioni iniziando ad ordinare l'array a partire dall'ultimo elemento per poi risalire.

Questo algoritmo è usato solo per scopi didattici o quando gli elementi da ordinare sono pochi poiché, siccome richiede una quantità di confronti troppo alta, risulta molto poco efficente (dell'ordine di ).

Implementazioni

Seguono alcune implementazioni in vari linguaggi.

Altre implementazioni si trovano qui su wikisource

void BubbleSort(int* array, int elemN)
{
  register int a, b,tmp=0, scambio;
  for (a=0; a<elemN-1; ++a)
  {
    scambio=0;
    for (b=a+1; b<elemN; ++b)
    {
      if (array[b] > array[b+1]) // scambiate il '>' con '<' se volete un ordinamento decrescente
      {
        tmp = array[b+1];
        array[b+1] = array[b];
        array[b] = tmp;
        scambio=1;
      }
    }
    if (!scambio) return; //esco se non ci sono stati scambi, inutile proseguire l'array è già ordinato
  }
}

Due note di carattere tecnico: a,b,tmp sono variabili dichiarate come register, il chè significa che, se possibile, il compilatore C farà in modo che vengano collocate nei registri della CPU; questo renderà più rapido l'accesso a dette variabili. tmp è dichiarata di tipo int, quindi dovrà contenere interi; se l'array contiene elementi di tipo diverso, sarà sufficiente modificare la sua dichiarazione.

#include <algorithm>
template <typename container> void bubbleSort(container &array)
{
  container::reverse_iterator  i;
  container::iterator j;
  for(i = array.rbegin(); i != array.rend(); ++i)
    for(j = array.begin(); j != i ; ++j)
      if((*j) > *(j+1) /* compara gli elementi vicini */
          std::swap(*j, *(j+1));
}

template<typename T> void bubble_sort(T *base, size_t n) {
   T *p, *q, t;    
   while (n--) { 
      for (q = (p = base) + 1; p < base + n; ++q, ++p) {
         (*p > *q) && (t = *p, *p = *q, *q = t);
      }
   }
}
public void bubbleSort(int[] array)
{
  int temp = 0;
  for(int i = array.length - 1; i > 0; i--)
    for(int j = 0; j < i; j++)
      if(array[j] > array[j+1]) // compara gli elementi vicini
      {                         // scambio
         temp = array[j+1];     
         array[j+1] = array[j];
         array[j] = temp;
      }
}
Sub Bubblesort(Array() as Integer, Length as Integer)
Dim I as Integer
Dim J as Integer
Dim Temp as Integer

   For I = Length -1 To 1 Step -1
      For J = 0 to I - 1
         IF Array(J)>Array(J+1) THEN  ' compara gli elementi vicini
            Temp = Array(j) 
            Array(J) = Array(J+1)
            Array(J+1) = Temp
         End If
      Next J
   Next I

End Sub
sub bubble_sort(@) {
  my @a = @_;
  foreach $i (reverse 0..@#a) {
    foreach $j (0..$i-1) {
        ($a[$j],$a[$j+1]) = ($a[$j+1],$a[$j]) if ($a[$j] > $a[$j+1]);
    }
  }
  return @a;
}
def bubblesort(iterable):
    seq = list(iterable)
    for passesLeft in range(len(seq)-1, 0, -1):
        for index in range(passesLeft):
            if seq[index] > seq[index + 1]:
                seq[index], seq[index + 1] = seq[index + 1], seq[index]
    return seq
      SUBROUTINE Bubble (X,N)
      ! X e' l'array da ordinare, di dimensione N
      IMPLICIT NONE
      INTEGER :: N, J, I, JMAX, TEMP
      INTEGER :: X(N) 
      JMAX=N-1
      spike1: DO I=1,N-1
         spike2: DO J=1,JMAX
             IF(X(J).GT.X(J+1)) GO TO 100
             TEMP=X(J)
             X(J)=X(J+1)
             X(J+1)=TEMP
 100     END DO spike2
        JMAX=JMAX-1
     END DO spike1
     RETURN
     END
(DEFUN bubble-sort (X)
  (LET ((Bubble (bubble X)))
    (IF (EQUAL X Bubble) X (bubble-sort Bubble))))

(DEFUN bubble (X)
  (COND ((NULL X) X)
        ((= (LENGTH X) 1) X)
        ((LISTP X) 
         (IF (> (CADR X) (CAR X)) 
             (CONS (CADR X) 
                   (bubble (CONS (CAR X) (CDR X)))) 
             (CONS (CAR X) (bubble (CDR X)))))
        (T (ERROR "bubble expects a list"))))
-- Nota: AppleScript è 1-based, cioè il primo elemento di una lista è 1
--
on bubblesort( array )
    repeat with i from length of array to 2 by -1 --> go backwards
        repeat with j from 1 to i - 1 --> go forwards
            tell array 
                if item j > item ( j + 1 ) then
                    set { item j, item ( j + 1 ) } to { item ( j + 1 ), item j } -- swap
                end if
            end tell
        end repeat
    end repeat
end bubblesort