See also ebooksgratis.com: no banners, no cookies, totally FREE.

CLASSICISTRANIERI HOME PAGE - YOUTUBE CHANNEL
Privacy Policy Cookie Policy Terms and Conditions
Ordenamiento por mezcla - Wikipedia, la enciclopedia libre

Ordenamiento por mezcla

De Wikipedia, la enciclopedia libre

El algoritmo de Ordenamiento por mezcla (Merge sort en inglés) es un algoritmo de ordenación externo estable basado en la técnica divide y vencerás. Es de complejidad O(n log n).

[editar] Descripción

Fue desarrollado en 1945 por John Von Neumann.

A grandes rasgos, el algoritmo consiste en dividir en dos partes iguales el vector a ordenar, ordenar por separado cada una de las partes, y luego mezclar ambas partes, manteniendo la ordenación, en un solo vector ordenado.

A continuación se describe el algoritmo en pseudocódigo (se advierte de que no se incluyen casos especiales para vectores vacíos, etc.; una implementación en un lenguaje de programación real debería tener en cuenta estos detalles):

function mergesort(array A[0..n])
begin
  array A1 := mergesort(A[0..(int(n / 2))])
  array A2 := mergesort(A[int(1 + n / 2)..n])
  return merge(A1, A2)
end

function merge(array A1[0..n1], array A2[0..n2])
begin
  integer p1 := 0
  integer p2 := 0
  array R[0..(n1 + n2 + 1)]
  while (p1 <= n1 or p2 <= n2):
    if (p1 <= n1 and A1[p1] <= A2[p2]):
      R[p1 + p2] := A1[p1]
      p1 := p1 + 1
    if (p2 <= n2 and A1[p1] > A2[p2]):
      R[p1 + p2] := A2[p2]
      p2 := p2 + 1
  return R
end

[editar] Implementaciones

El algoritmo Ordenamiento por mezcla (Merge Sort) en Perl

sub mergesort {
    mergesort_recursivo ($_[0], 0, $#{ $_[0] });  # Recibimos una referencia a un array
}
 
sub mergesort_recursivo {
    my ( $array, $primero, $ultimo ) = @_;
 
    if ( $ultimo > $primero ) {
        local $^W = 0;              # Quitamos el aviso de exceso de recursión
 
        my $mitad = int(( $ultimo + $primero ) / 2);
        mergesort_recursivo( $array, $primero, $mitad );
        mergesort_recursivo( $array, $mitad + 1, $ultimo );
        merge( $array, $primero, $mitad, $ultimo );
    }
}
 
my @work; # Una variable global.
 
sub merge {
    my ( $array, $primero, $mitad, $ultimo ) = @_;
    my $n = $ultimo - $primero + 1;
 
    # Inicializa @work con elementos importantes del array
    for ( my $i = $primero, my $j = 0; $i <= $ultimo; ) {
        $work[ $j++ ] = $array->[ $i++ ];
    }
 
    # Ahora hace la verdadera mezcla. Atraviesa el array
    # y copia los elementos en orden inverso al array original
    # $i es el índice del resultado de la mezcla, $j es el índice en
    # la primera mitad de la copia de trabajo, $k el índice de la segunda mitad.
 
    $mitad = int(($primero + $ultimo) / 2) if $mitad > $ultimo;
    my $n1 = $mitad - $primero + 1;      # El tamaño de la primera mitad.
 
    for ( my $i = $primero, my $j = 0, my $k = $n1;
          $i <= $ultimo;
          $i++ ) {
 
            $array->[ $i ] =
                              $j < $n1
                           &&
                              ( $k == $n || $work[ $j ] < $work[ $k ] ) 
                              ? $work[ $j++ ]
                              : $work[ $k++ ]
                           ;
    }
}

En C++

// En el código usamos la clase vector (#include <vector>) para crear los vectores,
// obviamente funciona igual de bien si se utilizan los arrays tipo C: TIPO V[]
template <class T>
void fusiona(vector<T>& v, int ini, int med, int fin) {
    vector<T> aux(fin - ini + 1);
    int i = ini; // Índice de la parte izquierda
    int j = med + 1; // Índice de la parte derecha
    int k = 0; // Índice del vector aux
 
 
    /* Mientras ninguno de los indices llegue a su fin vamos realizando
       comparaciones. El elemento más pequeño se copia al vector aux */
    while (i <= med and j <= fin) {
        if (v[i] < v[j]) {
            aux[k] = v[i];
            ++i;
        }
        else {
            aux[k] = v[j];
            ++j;
        }
        ++k;
    }
 
    /* Uno de los dos sub-vectores ya ha sido copiado del todo, simplemente
       debemos copiar todo el sub-vector que nos falte */
    while (i <= med) {
        aux[k] = v[i];
        ++i;
        ++k;
    }
 
    while (j <= fin) {
        aux[k] = v[j];
        ++j;
        ++k;
    }
 
    /* Copiamos los elementos ordenados de aux al vector original v */
    for (int n = 0; n < aux.size(); ++n) v[ini + n] = aux[n];
}
 
template <class T>
void merge_sort(vector<T>& v, int ini, int fin) {
    /* Si ini = fin el sub-vector es de un solo elemento y, por lo tanto
       ya está ordenado por definición */
    if (ini < fin) {
        int med = (ini + fin)/2;
        merge_sort(v, ini, med);
        merge_sort(v, med + 1, fin);
        fusiona(v, ini, med, fin);
    }
}

[editar] Enlaces externos


aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -