Vous êtes sur la page 1sur 15

Ordenamiento por insercin

Ejemplo de ordenamiento por insercin ordenando una lista de nmeros aleatorios. El ordenamiento por insercin (insertion sort en ingls) es una manera muy natural de ordenar para un ser humano, y puede usarse fcilmente para ordenar un mazo de cartas numeradas en forma arbitraria. Requiere O(n) operaciones para ordenar una lista de n elementos. Inicialmente se tiene un solo elemento, que obviamente es un conjunto ordenado. Despus, cuando hay k elementos ordenados de menor a mayor, se toma el elemento k+1 y se compara con todos los elementos ya ordenados, detenindose cuando se encuentra un elemento menor (todos los elementos mayores han sido desplazados una posicin a la derecha). En este punto se inserta el elemento k+1 debiendo desplazarse los dems elementos.

Ejemplo de funcionamiento
En el siguiente ejemplo, 32 debe ser insertado entre 26 y 47, y por lo tanto 47, 59 y 96 deben ser desplazados.
k+1 11 26 47 59 96 32 11 26 47 59 96 11 26 32 47 59 96

En la implementacin computacional, el elemento k+1 va comparndose de atrs para adelante, detenindose con el primer elemento menor. Simultneamente se van haciendo los desplazamientos.
11 26 47 59 96 32 11 26 47 59 96 11 26 47 59 96 11 26 47 59 96 11 26 32 47 59 96

El algoritmo en pseudocdigo (con listas que empiezan por 0) debera ser como el siguiente:
algoritmo insertSort( A : lista de elementos ordenables ) para i=1 hasta longitud(A) hacer index=A[i] j=i-1 mientras j>=0 y A[j]>index hacer A[j+1] = A[j] j=j-1 fin mientras A[j+1] = index fin para fin algoritmo

Aunque este algoritmo tiene un mejor orden de complejidad que el de burbuja, es muy ineficiente al compararlo con otros algoritmos como quicksort. Sin embargo, para listas relativamente pequeas el orden por insercin es una buena eleccin, no slo porque puede ser ms rpido para cantidades pequeas de elementos sino particularmente debido a su facilidad de programacin.

Implementacin
A continuacin se muestra el Ordenamiento por insercin en distintos lenguajes de programacin:
C
void insertionSort(int numbers[], int array_size) { int i, a, index; for (i=1; i < array_size; i++) { index = numbers[i]; for (a=i-1;a >= 0 && numbers[a] > index;a--) { numbers[a + 1] = numbers[a]; } numbers[a+1] = index; } }

C++
template <class T> void insertionSort(std::vector<T>& v, int fin) { int i, j, index; for (i=1; i <fin; i++) { index = v.at(i); j = i-1; while (j >= 0 && v.at(j)>index) { v.at(j+1)=v.at(j); j--; } v.erase(v.begin()+j+1); v.insert(v.begin()+j+1,index); } }

Java
public static void insertSort (int[] v) { int aux; int j; for (int i=1; i<v.length; i++) { aux = v[i]; for (j=i-1; j>=0 && v[j]>aux; j--){ v[j+1] = v[j]; v[j] = aux; } } }

JavaScript
for (var i=1; i < vector.length; i++) { var temp = vector[i]; var j = i-1; while (j >= 0 && vector[j] > temp) { vector[j + 1] = vector[j]; j--; }

vector[j+1] = temp; }

Perl
#!/usr/bin/perl use v5.12; my @array = qw( 1749472308 ); insercion(\@array); say "@array"; sub insercion { my $array_ref = shift; for my $i (1 .. $#$array_ref) { my $j = $i - 1; my $x = $array_ref->[$i]; next if $array_ref->[$j] <= $x; # 1 arg. es una ref. a un array # para todos los ndices # ndice anterior # elemento a comparar # salida rpida

do { $j--; # buscamos } while ($j >= 0 and $array_ref->[$j] > $x); } } __END__ 0123447789 splice @$array_ref, $j+1, 0, splice @$array_ref, $i, 1; # extraccin e insercin!

PHP
function insert_sort($arr){ $count = count($arr); for($i=1; $i<$count; $i++){ $tmp = $arr[$i]; for ($j=$i-1; $j>=0 && $arr[$j] > $tmp; $j--) $arr[$j+1] = $arr[$j]; $arr[$j+1] = $tmp; } return $arr; }

Pascal
Procedure InsertionSort(var insertion:Array_integer; array_size: Integer); Var i, j, index : Integer; Begin For i := 1 to array_size do Begin index := insertion[i]; j := i-1; While ((j >= 0) AND (insertion[j] > index)) do Begin

insertion[j+1] := insertion[j]; j := j - 1; End; insertion[j+1] := index; End; End;

Python
def insertionSort(numeros): #numeros es una lista tama = len(numeros) #creamos una variable igual al tamao de la lista for i in range(tama): indice = numeros[i] a = i-1 while (a >= 0 and numeros[a] > indice): numeros[a+1] = numeros[a] a = a-1 numeros[a+1] = indice print (numeros) #imprime la lista ordenada

Ruby
def insertion_sort(array) for j in 1...array.size key = array[j] i=j-1 while i >= 0 and array[i] > key array[i + 1] = array[i] i=i-1 end array[i + 1] = key end array end

Visual Basic .NET


Private Sub insertionSort(ByVal numbers() As Integer) ' Es una funcin, 'debemos pasarle el array de nmeros desde el Sub Main() Dim i, j, index As Integer i=1 Do index = numbers(i) j=i-1 While ((j >= 0) And (numbers(j) > index)) numbers(j + 1) = numbers(j) j=j-1 End While numbers(j + 1) = index i=i+1 Loop Until i > (UBound(v)) End Sub

C#
class Program { public static void Main(string[] args) { int x=0; do{ Leer leer=new Leer();

} }

leer.dato(); Console.WriteLine("Repitiendo..."); }while(x==0); Console.ReadKey(true);

public class Inserccion_Directa { private static int temporal, posicion=0; static int[] x=new int[15]; public int ordenar(int entrada){ x[posicion]=entrada; posicion++; for(int y=1;y<posicion;y++){ temporal=x[y]; for(int z=y-1;z>=0 && x[z]>temporal; z--){ x[z+1] = x[z]; x[z] = temporal; } } for(int m=0;m<x.Length;m++){ Console.WriteLine("Contenido "+x[m]); } return 0; } } public class Leer{ int cadena; public int dato(){ cadena=Convert.ToInt32(Console.ReadLine()); Inserccion_Directa objeto1=new Inserccion_Directa(); objeto1.ordenar(cadena); return cadena; } }

Ordenamiento por seleccin

Animacin del Selection Sort

El ordenamiento por seleccin (Selection Sort en ingls) es un algoritmo de ordenamiento que requiere O(n2) operaciones para ordenar una lista de n elementos. Su funcionamiento es el siguiente:
Buscar el mnimo elemento de la lista Intercambiarlo con el primero Buscar el mnimo en el resto de la lista Intercambiarlo con el segundo Buscar el mnimo elemento entre una posicin i y el final de la lista Intercambiar el mnimo con el elemento de la posicin i

Y en general:

De esta manera se puede escribir el siguiente pseudocdigo para ordenar una lista de n elementos indexados desde el 1:
para i=1 hasta n-1 minimo = i; para j=i+1 hasta n si lista[j] < lista[minimo] entonces minimo = j /* (!) */ fin si fin para intercambiar(lista[i], lista[minimo]) fin para

Este algoritmo mejora ligeramente el algoritmo de la burbuja. En el caso de tener que ordenar un vector de enteros, esta mejora no es muy sustancial, pero cuando hay que ordenar un vector de estructuras ms complejas, la operacin intercambiar() sera ms costosa en este caso. Este algoritmo realiza muchas menos operaciones intercambiar() que el de la burbuja, por lo que lo mejora en algo. Si la lnea comentada con (!) se sustituyera por intercambiar(lista[i], lista[j]) tendramos una versin del algoritmo de la burbuja (naturalmente eliminando el orden intercambiar del final). Otra desventaja de este algoritmo respecto a otros como el de burbuja o de insercin directa es que no mejora su rendimiento cuando los datos ya estn ordenados o parcialmente ordenados. As como, por ejemplo, en el caso de la ordenacin de burbuja se requerira una nica pasada para detectar que el vector ya est ordenado y finalizar, en la ordenacin por seleccin se realizaran el mismo nmero de pasadas independientemente de si los datos estn ordenados o no.

Rendimiento del algoritmo


Artculo principal: Cota ajustada asinttica

Al algoritmo de ordenamiento por seleccin, para ordenar un vector de n trminos, tiene que realizar siempre el mismo nmero de comparaciones:

Esto es, el nmero de comparaciones c(n) no depende del orden de los trminos, si no del nmero de trminos.

Por lo tanto la cota ajustada asinttica del nmero de comparaciones pertenece al orden de n cuadrado. El nmero de intercambios i(n), tambin es fijo, tngase en cuenta que la instruccin:
intercambiar(lista[i], lista[minimo])

siempre se ejecuta, aun cuando i= minimo, lo que da lugar:

sea cual sea el vector, y el orden de sus trminos, lo que implica en todos los casos un coste lineal:

la cota ajustada asinttica del numero de intercambios es lineal, del orden de n.

Implementaciones
Java

void selecccion(int[] a) { for (int i = 0; i < a.length - 1; i++) { int min = i; for (int j = i + 1; j < a.length; j++) { if (a[j] < a[min]) { min = j; } } if (i != min) { int aux= a[i]; a[i] = a[min]; a[min] = aux; } } }

void ordsel(int * x, int n) { int minimo=0,i,j; int swap; for(i=0 ; i<n-1 ; i++) { minimo=i; for(j=i+1 ; j<n ; j++) if (x[minimo] > x[j]) minimo=j; swap=x[minimo]; x[minimo]=x[i]; x[i]=swap; } }

Basic

For i = 1 To n - 1 minimo = i For j = i + 1 To n If x(minimo) > x(j) Then minimo = j End If Next j temp = x(i) x(i) = x(minimo) x(minimo) = temp Next i

C++

#include <iostream> #include <vector> using namespace std; template <class T> void ordena_seleccion(vector<T>& v) { for (int i = 0; i < v.size(); ++i) { int min = i; for (int c = i + 1; c < v.size(); ++c) {

if (v[min] > v[c]) min = c; } T aux = v[i]; v[i] = v[min]; v[min] = aux; } }

Perl
# Recibimos una referencia a un array

sub seleccion { my $array = shift; my $i; my $j;

# ndice del elemento a comparar # ndice del valor mnimo a encontrar

# Para todos los elementos menos el ltimo for ( $i = 0; $i < $#$array; $i++ ) { # ndice y valor del elemento a comparar my ( $m, $x ) = ( $i, $array->[ $m ] ); # Buscamos el valor ms pequeo de todos los dems for ( $j = $i + 1; $j < @$array; $j++ ) { ( $m, $x ) = ( $j, $array->[ $j ] ) # Nuevo mnimo encontrado if $array->[ $j ] < $x;

} }

# Hacemos el intercambio de elementos, si es necesario @$array[ $m, $i ] = @$array[ $i, $m ] if $m != $i;

JavaScript

for(var i=0 ; i<vector.length-1 ; i++) { var menor = i; for(var j=i+1 ; j<vector.length ; j++) { if (vector[menor] > vector[j]) menor = j; } var temp = vector[menor]; vector[menor] = vector[i]; vector[i] = temp; }

PHP

function IntercambiarElementos(&$arreglo,$pos1,$pos2){ $aux=$arreglo[$pos1]; $arreglo[$pos1]=$arreglo[$pos2]; $arreglo[$pos2]=$aux; } function PosicionMenorElemento($arreglo,$posinicial){ $posmenor=$posinicial; for($i=$posinicial+1;$i<count($arreglo);$i++){ if($arreglo[$i]<$arreglo[$posmenor]){ $posmenor=$i; } } return $posmenor; }

function OrdenamientoPorSeleccion(&$arreglo){ for($i=0;$i<count($arreglo);$i++){ $posmenor=PosicionMenorElemento($arreglo,$i); if($posmenor>$i){ IntercambiarElementos($arreglo,$i,$posmenor); } } }

Python

def seleccion(lista) n = len(lista) for i in range(0,n-1): k=i t = lista[i] for j in range(i,n): if lista[j] < t: k=j t = lista[j] lista[k] = lista[i] lista[i] = t return lista

Pascal

Procedure OrdSel (var Sec : TipSec; TamSec : Integer); var i, j, min, num : Integer; begin for i := 1 to TamSec-1 do begin min := i; for j := i+1 to TamSec do begin if Sec[j] < Sec[min] then min := j; end; num := Sec[min]; Sec[min] := Sec[i]; Sec[i] := num; end; end;

Game Maker Language

// array de extensin n for(i=0 ; i<n-1 ; i+=1) { menor = i; for(j=i+1 ; j<n; j+=1) { if (vector[menor] > vector[j]) {menor = j;} } temp = vector[menor]; vector[menor] = vector[i]; vector[i] = temp; }

Bsqueda Hash En este mtodo se requiere que los elementos estn ordenados. El mtodo consiste en asignar el ndice a cada elemento mediante una transformacin del elemento, esto se hace mediante una funcin de conversin llamada funcin hash. Hay diferentes funciones para transformar el elemento y el nmero obtenido es el ndice del elemento. La principal forma de transformar el elemento es asignarlo directamente, es decir al 0 le corresponde el ndice 0, al 1 el 1, y as sucesivamente pero cuando los elementos son muy grandes se desperdicia mucho espacio ya que necesitamos arreglo grandes para almacenarlos y estos quedan con muchos espacios libres, para utilizar mejor el espacio se utilizan funciones mas complejas. La funcin de hash ideal debera ser biyectiva, esto es, que a cada elemento le corresponda un ndice, y que a cada ndice le corresponda un elemento, pero no siempre es fcil encontrar esa funcin, e incluso a veces es intil, ya que puedes no saber el nmero de elementos a almacenar. La funcin de hash depende de cada problema y de cada finalidad, y se pueden utilizar con nmeros o cadenas, pero las ms utilizadas son: 1.- Restas sucesivas: Esta funcin se emplea con claves numricas entre las que existen huecos de tamao conocido, obtenindose direcciones consecutivas. Un ejemplo serian los alumnos de ingeniera en sistemas que entraron en el ao 2005 sus nmeros de control son consecutivos y esta definido el numero de alumnos. 05210800 -05210800 0 05210801 -05210800 1

05210802 -05210800 2 05210899 -05210800 99 2.- Aritmtica modular: El ndice de un nmero es resto de la divisin de ese nmero entre un nmero N prefijado, preferentemente primo. Los nmeros se guardarn en las direcciones de memoria de 0 a N-1. Este mtodo tiene el problema de que dos o ms elementos pueden producir el mismo residuo y un ndice puede ser sealado por varios elementos. A este fenmeno se le llama colisin. Si el nmero N es el 7, los nmeros siguientes quedan transformados en: 1679 > 6 4567 > 3 8471 > 1 0435 > 1 5033 > 0 Mientras mas grande sea nmero de elementos es mejor escoger un nmero primo mayor para seccionar el arreglo en ms partes. El nmero elegido da el nmero de partes en que se secciona el arreglo, y las cada seccin esta compuesta por todos los elementos que arrojen el mismo residuo, y mientras mas pequeas sean las secciones la bsqueda se agilizara mas que es lo que nos interesa. 3.- Mitad del cuadrado: Consiste en elevar al cuadrado la clave y coger las cifras centrales. Este mtodo tambin presenta problemas de colisin. 709^2=502681 > 26 456^2=207936 > 79 105^2=11025 > 10 879^2=772641 > 26 619^2=383161 > 31 Nota: en caso de que la cifra resultante sea impar se toma el valor nmero y el anterior. 4.- Truncamiento: Consiste en ignorar parte del nmero y utilizar los elementos restantes como ndice. Tambin se produce colisin. Por ejemplo, si un nmero de 7 cifras se debe ordenar en un arreglo de elementos, se pueden tomar el segundo, el cuarto y el sexto para formar un nuevo nmero: 5700931 > 703 3498610 > 481 0056241 > 064 9134720 > 142 5174829 > 142 5.- Plegamiento: Consiste en dividir el nmero en diferentes partes, y operar con ellas (normalmente con suma o multiplicacin). Tambin se produce colisin. Por ejemplo, si dividimos el

nmero de 7 cifras en 2, 2 y 3 cifras y se suman, dar otro nmero de tres cifras (y si no, se toman las tres ltimas cifras): 5700931 > 57 + 00 + 931 = 988 3498610 > 34 + 98 + 610 = 742 0056241 > 00 + 56 + 241 = 297 9134720 > 91 + 34 + 720 = 845 5174929 > 51 + 74 + 929 = 1054 Nota: Estas solo son sugerencias y que con cada problema se pude implementar una nueva funcin hash que incluso tu puedes inventar o formular. Tratamiento de colisiones Hay diferentes maneras de solucionarlas pero lo ms efectivo es en vez de crear un arreglo de nmero, crear un arreglo de punteros, donde cada puntero seala el principio de una lista enlazada. As, cada elemento que llega a un determinado ndice se pone en el ltimo lugar de la lista de ese ndice. El tiempo de bsqueda se reduce considerablemente, y no hace falta poner restricciones al tamao del arreglo, ya que se pueden aadir nodos dinmicamente a la lista. PRUEBA LINEAL Consiste en que una vez detectada la colisin se debe recorrer el arreglo secuencialmente a partir del punto de colisin, buscando al elemento. El proceso de bsqueda concluye cuando el elemento es hallado, o bien cuando se encuentra una posicin vaca. Se trata al arreglo como a una estructura circular: el siguiente elemento despus del ltimo es el primero. La funcin de rehashing es, por tanto, de la forma: R(H(X)) = (H(X) + 1) % m (siendo m el tamao del arreglo) Ejemplo: Si la posicin 397 ya estaba ocupada, el registro con clave 0596397 es colocado en la posicin 398, la cual se encuentra disponible. Una vez que el registro ha sido insertado en esta posicin, otro registro que genere la posicin 397 o la 398 es insertado en la posicin siguiente disponible. Ejemplo: Tomando en cuenta los datos de la seccin 2 de este tema crea un programa que mediante bsqueda hash encuentre los datos requeridos y asegurate de tratar las colisiones.
using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; System.IO;

namespace WindowsApplication1 { public partial class Form1 : Form { private int[] datos = new int[5] {1679, 4567, 8471, 0435, 5033 }; private int[] hash = new int[7]; private int[] enlace = new int[7]; public Form1() { InitializeComponent(); for (int b = 0; b <= 6; b++)

{ enlace[b] = -9999; } //Reacomodo por hash int r, aux=0; for (int i = 0; i <= 4; i++) { r= datos[i] % 7; if (datos[i] == 0) { hash[r] = datos[i]; } else { for(int s=0;s<=6;s++) { if(hash[s]==0) { aux=s; } } hash[aux]=datos[i]; enlace[r] = aux; } } } private void buscar_Click(object sender, EventArgs e) { int temp,r; temp = int.Parse(textBox1.Text.ToString()); r = temp % 7; if (temp == hash[r]) { MessageBox.Show("Se encuentra en \nel renglon:" + r.ToString(), "Resultado"); } else { while(enlace[r] != -9999) { if (temp == hash[enlace[r]]) { MessageBox.Show("Se encuentra en \nel renglon:" + enlace[r].ToString(), "Resultado"); r = enlace[r]; } } } } } }

Imagenes de programa corriendo:

Vous aimerez peut-être aussi