República Bolivariana de Venezuela
Ministerio del Poder Popular para la Educación
Universidad Nororiental Privada Gran Mariscal de Ayacucho
Núcleo Bolívar
Ingeniería en Informática
Tutoría de Programación III
ESTRUCTURAS DE ALMACENAMIENTO DE DATOS –
VECTORES EN VISUAL C# .NET
Profesor: Alumno:
Jesús Abello Jesús Alexis Díaz Pérez
C.I: 27.255.236
Madeleinne Belisario
C.I: 26.692.709
Ciudad Bolívar, 23 de Noviembre de 2020
Vectores en C#
Qué es un vector? Un vector (o arreglo unidimensional) es una estructura de datos en
la cual se almacena un conjunto de datos de un mismo tipo. Es decir que un arreglo es
una lista de n elementos que posee las siguientes características:
Se identifica por un único nombre de variable.
Sus elementos se almacenan en posiciones contiguas de memoria.
Se accede a cada uno de sus elementos en forma aleatoria.
Métodos de Búsqueda
Búsqueda Binaria en C#
El algoritmo de búsqueda binaria es un excelente método para buscar datos dentro de
una estructura(generalmente un arreglo unidimencional). Se le da el nombre de
búsqueda binaria por que el algoritmo divide en dos el arregelo, aludiendo al concepto
de bit, el cual puede tener dos estados.
La única condición para usar este algoritmo es que los datos dentro del arreglo estén
ordenados de menor a mayor.
La solución más fácil para realizar una busqueda es por fuerza bruta, pero este método
puede resultar bastante ineficiente cuando se tiene una gran cantidad de datos, ya que
habria que buscar posición por posición hasta encontrar el dato que queremos.
El código por fuerza bruta es bastante sencillo:
for(int i=0; i<Arreglo.length; i++)
if(Arreglo[i] == elemento)
System.out.println("\nElemento encontrado en la posicion: " + i);
Solo se recorre todo el arreglo y verificamos si la posición i es igual al dato que
queremos buscar, el código anterior se puede mejorar simplemente agregandole una
bandera, pero aun asi no es lo suficientemente bueno.
El algoritmo de búsqueda binaria es el siguiente:
1. Se declaran los índices superior e inferior. El inferior en 0 y el superior con el
tamaño del arreglo menos 1.
2. Se calcula el centro del arreglo con la siguiente formula: centro = (superior +
inferior) / 2
3. Verificamos si el arreglo en la posición centro es igual al dato que buscamos. Si
es igual significa que encontramos el dato y retornamos centro.
4. Si son diferentes verificamos si el arreglo en la posición centro es mayor al dato
que queremos buscar. Si es mayor actualizamos superior: superior = centro - 1,
si no actualizamos inferior: inferior = centro + 1.
5. Volvemos al paso 2.
Si cuando ya no se cumpla la condicón del ciclo y no se encontro el dato retornamos -1
indicando que el dato no se encuentra en el arreglo.
Búsqueda Binaria
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BusquedaBinaria
class Busqueda
private int[] vector;
public void Cargar()
Console.WriteLine("Busqueda Binaria");
Console.WriteLine("Ingrese 10 Elementos");
string linea;
vector = new int[10];
for (int f = 0; f < vector.Length; f++)
Console.Write("Ingrese elemento " + (f + 1) + ": ");
linea = Console.ReadLine();
vector[f] = int.Parse(linea);
public void busqueda(int num)
int l = 0, h = 9;
int m = 0;
bool found = false;
while (l <= h && found == false)
m = (l + h) / 2;
if (vector[m] == num)
found = true;
if (vector[m] > num)
h = m - 1;
else
l = m + 1;
if (found == false)
{ Console.Write("\nEl elemento {0} no esta en el arreglo", num); }
else
{ Console.Write("\nEl elemento {0} esta en la posicion: {1}", num, m + 1); }
public void Imprimir()
for (int f = 0; f < vector.Length; f++)
Console.Write(vector[f] + " ");
static void Main(string[] args)
Busqueda pv = new Busqueda();
pv.Cargar();
pv.Imprimir();
Console.Write("\n\nElemento a buscar: ");
int num = int.Parse(Console.ReadLine());
pv.busqueda(num);
Console.ReadKey();
}
Búsqueda HASH
En este método se requiere que los elementos estén ordenados. El método consiste en
asignar el índice a cada elemento mediante una transformación del elemento, esto se
hace mediante una función de conversión llamada función hash. Hay diferentes
funciones para transformar el elemento y el número 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 más complejas.
La función de hash ideal debería 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 fácil encontrar esa función, e incluso a veces es inútil, ya que puedes no
saber el número de elementos a almacenar. La función de hash depende de cada
problema y de cada finalidad, y se pueden utilizar con números o cadenas, pero las
más utilizadas son:
Restas sucesivas
Esta función se emplea con claves numéricas entre las que existen huecos de tamaño
conocido, obteniéndose direcciones consecutivas. Un ejemplo serian los alumnos de
ingeniería en sistemas que entraron en el año 2005 sus números de control son
consecutivos y está definido el número de alumnos.
05210800 -05210800»» 0
05210801 -05210800»» 1
05210802 -05210800»» 2
05210899 -05210800»» 99
Aritmética modular
El índice de un número es resto de la división de ese número entre un número N
prefijado, preferentemente primo. Los números se guardarán en las direcciones de
memoria de 0 a N-1. Este método tiene el problema de que dos o más elementos
pueden producir el mismo residuo y un índice puede ser señalado por varios
elementos. A este fenómeno se le llama colisión. Si el número N es el 7, los números
siguientes quedan transformados en:
1679 »> 6
4567 »> 3
8471 »> 1
0435 »> 1
5033 »> 0
Mientras mas grande sea número de elementos es mejor escoger un número primo
mayor para seccionar el arreglo en más partes. El número elegido da el número de
partes en que se secciona el arreglo, y las cada sección esta compuesta por todos los
elementos que arrojen el mismo residuo, y mientras mas pequeñas sean las secciones
la búsqueda se agilizara mas que es lo que nos interesa.
Mitad del cuadrado
Consiste en elevar al cuadrado la clave y coger las cifras centrales. Este método
también presenta problemas de colisión.
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 número y el anterior.
Truncamiento
Consiste en ignorar parte del número y utilizar los elementos restantes como índice.
También se produce colisión. Por ejemplo, si un número 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 número:
5700931 »> 703
3498610 »> 481
0056241 »> 064
9134720 »> 142
5174829 »> 142
Plegamiento
Consiste en dividir el número en diferentes partes, y operar con ellas (normalmente con
suma o multiplicación). También se produce colisión. Por ejemplo, si dividimos el
número de 7 cifras en 2, 2 y 3 cifras y se suman, dará otro número 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 función hash que incluso tu puedes inventar o formular.
Tratamiento de colisiones
Hay diferentes maneras de solucionarlas pero lo más efectivo es en vez de crear un
arreglo de número, crear un arreglo de punteros, donde cada puntero señala 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 búsqueda se reduce
considerablemente, y no hace falta poner restricciones al tamaño del arreglo, ya que se
pueden añadir nodos dinámicamente a la lista.
Prueba lineal
Consiste en que una vez detectada la colisión se debe recorrer el arreglo
secuencialmente a partir del punto de colisión, buscando al elemento. El proceso de
búsqueda concluye cuando el elemento es hallado, o bien cuando se encuentra una
posición vacía. Se trata al arreglo como a una estructura circular: el siguiente elemento
después del último es el primero. La función de rehashing es, por tanto, de la forma:
R(H(X)) = (H(X) + 1) % m (siendo m el tamaño del arreglo) Ejemplo: Si la posición 397
ya estaba ocupada, el registro con clave 0596397 es colocado en la posición 398, la
cual se encuentra disponible. Una vez que el registro ha sido insertado en esta
posición, otro registro que genere la posición 397 o la 398 es insertado en la posición
siguiente disponible.
Programa en Esctructura de Datos C# que utiliza Búsqueda Hash
Código Fuente
class Hash
Random r = new Random();
int[] K = new int[50];
int[] V = new int[50];
public void Generar()
for (int i = 0; i < 50; i++)
K[i] = r.Next(10210000, 10210100);
public void llenado()
for (int s = 0; s < 50; s++)
V[s] = 0;
public void Desplegar()
{
if (K[0] == 0)
Console.WriteLine("El Arreglo esta vacio");
else
int iter = 0;
int pos = 0;
Console.Write("\n");
for (int i = 0; i < 10; i++)
for (int D = 0; D < 5; D++)
pos++;
Console.Write("{0}.-{1}\t ", pos, K[iter]);
iter++;
Console.Write("\n");
public void Desplegar1()
{
int iter = 0;
int pos = 0;
Console.Write("\n");
for (int i = 0; i < 10; i++)
for (int D = 0; D < 5; D++)
pos++;
Console.Write("{0}.-{1}\t ", pos, V[iter]);
iter++;
Console.Write("\n");
public void AsignarDirecciones()
int N = 49, D, DX, I;
for (I = 0; I <= N; I++)
D = (K[I] % N) + 1;
while (V[D] != 0)
{
DX = D + 1;
if (DX > N)
D = 0;
else
D = DX;
V[D] = K[I];
Console.WriteLine("Posiciones asignadas");
public void Busqueda()
int n = 50, D, DX;
Console.Write("Introduzca el Dato que desee Buscar: ");
int KEY = Int32.Parse(Console.ReadLine());
D = (KEY % (n - 1)) + 1;
if (V[D] == KEY)
{
Console.WriteLine("elemento {0} Esta en la Poscion {1}", KEY, D + 1);
else
DX = D + 1;
while ((DX <= (n - 1)) && (V[DX] != KEY) && (V[DX] != 0) && (DX != D))
DX = DX + 1;
if (DX > (n - 1))
DX = 0;
if (V[DX] == KEY)
Console.WriteLine("El elemento {0} Esta en la posicion {1} ", KEY, (DX +
1));
else
Console.WriteLine("El elemento {0} NO esta en el Arreglo", KEY);
}
}
static void Main(string[] args)
char otra;
int resp = 0;
Hash H1 = new Hash();
do
Console.Clear();
Console.WriteLine(" Ordenamiento Hash ");
Console.WriteLine("1) Generar Arreglo");
Console.WriteLine("2) Desplegar Arreglo");
Console.WriteLine("3) Asignar posiciones");
Console.WriteLine("4) Buscar en el arreglo");
Console.WriteLine("5) Salir");
Console.Write("introduce una opción: ");
resp = Int32.Parse(Console.ReadLine());
Console.Clear();
switch (resp)
case 1:
H1.Generar();
H1.llenado();
Console.WriteLine("Presione ENTER para continuar");
Console.ReadLine();
break;
case 2:
Console.WriteLine("\tArreglo Original\n");
H1.Desplegar1();
Console.Write("\n\n");
Console.WriteLine("\tArreglo Generado\n");
H1.Desplegar();
Console.WriteLine("Presione ENTER para continuar");
Console.ReadLine();
break;
case 3:
H1.AsignarDirecciones();
Console.WriteLine("Presione ENTER para continuar");
Console.ReadLine();
break;
case 4:
do
H1.Desplegar1();
H1.Busqueda();
Console.Write("Desea realizar otra busqueda (s/n)?: ");
otra = Char.Parse(Console.ReadLine());
otra = Char.ToUpper(otra);
Console.Clear();
} while (otra == 'S');
break;
case 5:
Console.WriteLine("Presione ENTER para salir del programa");
Console.ReadLine();
break;
default:
Console.WriteLine("Opcion invalida, presione enter para continuar");
Console.ReadLine();
break;
} while (resp != 5);
Búsqueda Secuencial
Se utiliza cuando el vector no está ordenado o no puede ser ordenado previamente.
Consiste en buscar el elemento comparándolo secuencialmente (de ahí su nombre)
con cada elemento del arreglo hasta encontrarlo, o hasta que se llegue al final. La
existencia se puede asegurar cuando el elemento es localizado, pero no podemos
asegurar la no existencia hasta no haber analizado todos los elementos del arreglo.
A continuación se muestra el pseudocódigo del algoritmo:
Datos de entrada:
vec: vector en el que se desea buscar el dato
tam: tamaño del vector. Los subíndices válidos van desde 0 hasta tam-1 inclusive.
dato: elemento que se quiere buscar.
Variables
pos: posición actual en el arreglo
pos = 0
Mientras pos < tam:
Si vec[pos] == dato devolver verdadero y/o pos, de lo contrario:
pos = pos + 1
Fin (Mientras)
Devolver falso.
Métodos de Ordenamiento C#
Método de Ordenamiento Merge Sort en C#
Esta vez estaremos hablando de Ordenación por Mezcla (Merge Sort), otro algoritmo
recursivo bastante eficiente para ordenar un array, que tiene un orden de complejidad
O(nlogn) al igual que Quick Sort. Fue desarrollado en 1945 por John Von Neumann
según wikipedia.
Estrategia de Merge Sort
Merge Sort está basado en la técnica de diseño de algoritmos Divide y Vencerás, de la
cual se habló aquí mismo hace un tiempo. Recordando un poco, esta técnica consiste
en dividir el problema a resolver en sub problemas del mismo tipo que a su vez se
dividirán, mientras no sean suficientemente pequeños o triviales.
Veamos una panorámica de la estrategia que sigue este algoritmo para ordenar una
secuencia S de n elementos:
1) Si S tiene uno o ningún elemento, está ordenada}
2) Si S tiene al menos dos elementos se divide en dos secuencias S1 y S2
3) S1 contiene los primeros n/2 elementos y S2 los restantes
4) Ordenar S1 y S2, aplicando recursivamente este procedimiento
5) Mezclar S1 y S2 en S, de forma que ya S1 y S2 estén ordenados
Veamos ahora como sería la estrategia para mezclar las secuencias:
Se tienen referencias al principio de cada una de las secuencias a mezclar (S1 y S2).
Mientras en alguna secuencia queden elementos, se inserta en la secuencia resultante
(S) el menor de los elementos referenciados y se avanza esa referencia una posición.
Ejemplo del Método de Ordenamiento Merge Sort en C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MergeSort
class Program
static void Main(string[] args)
int[] nums = new int[40];
Console.WriteLine("Metodo de Merge Sort");
Console.Write("Cuantos longitud del vector: ");
string linea;
linea = Console.ReadLine();
int cant;
cant = int.Parse(linea);
nums = new int[cant];
for (int f = 0; f < nums.Length; f++)
Console.Write("Ingrese elemento " + (f + 1) + ": ");
linea = Console.ReadLine();
nums[f] = int.Parse(linea);
MergeSort(nums);
Console.WriteLine("Vector Ordenado Ascendentemente");
for (int i = 0; i < nums.Length; i++)
Console.Write(nums[i] + " ");
Console.ReadLine();
//Método portal que llama al método recursivo inicial
public static void MergeSort(int[] x)
MergeSort(x, 0, x.Length - 1);
static private void MergeSort(int[] x, int desde, int hasta)
//Condicion de parada
if (desde == hasta)
return;
//Calculo la mitad del array
int mitad = (desde + hasta) / 2;
//Voy a ordenar recursivamente la primera mitad
//y luego la segunda
MergeSort(x, desde, mitad);
MergeSort(x, mitad + 1, hasta);
//Mezclo las dos mitades ordenadas
int[] aux = Merge(x, desde, mitad, mitad + 1, hasta);
Array.Copy(aux, 0, x, desde, aux.Length);
//Método que mezcla las dos mitades ordenadas
static private int[] Merge(int[] x, int desde1, int hasta1, int desde2, int hasta2)
int a = desde1;
int b = desde2;
int[] result = new int[hasta1 - desde1 + hasta2 - desde2 + 2];
for (int i = 0; i < result.Length; i++)
if (b != x.Length)
{
if (a > hasta1 && b <= hasta2)
result[i] = x[b];
b++;
if (b > hasta2 && a <= hasta1)
result[i] = x[a];
a++;
if (a <= hasta1 && b <= hasta2)
if (x[b] <= x[a])
result[i] = x[b];
b++;
else
result[i] = x[a];
a++;
}
}
else
if (a <= hasta1)
result[i] = x[a];
a++;
return result;
Al ejecutar el código muestra el siguiente resultado
Método de Ordenamiento Burbuja en C#
Este método consiste en ir comparando cada par de elementos del array e ir moviendo
el mayor elemento hasta la última posición, comenzando desde la posición cero. Una
vez acomodado el mayor elemento, prosigue a encontrar y acomodar el segundo más
grande comparando de nuevo los elementos desde el inicio de la lista, y así sigue hasta
ordenar todos los elementos del arreglo. Al ser necesario revisar varias veces toda la
lista hasta que no se necesiten más intercambios, hace que el ordenamiento por
burbuja sea uno de los algoritmos más ineficientes que existen. Incluso entre los
algoritmos de ordenamiento del mismo orden, otros como el “Ordenamiento por
inserción” son considerados más eficientes. Y lo más curioso es que este
procedimiento es uno de los más usados para ordenar listas en todos los lenguajes de
programación.
Estos serían los pasos a seguir por este algoritmo para ordenar una lista a1, a2, a3, …
an
1) Comparar a1 con a2 e intercambiarlos si a1>a2
2) Seguir hasta que se haya comparado an-1 con an
3) Repetir el proceso anterior n-1 veces
Ejemplo:
25 57 48 37 12 92 86 33
En el primer paso se realizan las siguientes operaciones:
x[0] con x[1] (25 con 57) no intercambio.
x[1] con x[2] (57 con 48) intercambio.
x[2] con x[3] (57 con 32) intercambio.
x[3] con x[4] (57 con 12) intercambio.
x[4] con x[5] (57 con 92) no intercambio.
x[5] con x[6] (92 con 86) intercambio.
x[6] con x[7] (92 con 33) intercambio.
Así después del primer paso, el arreglo está en el siguiente orden:
25 48 37 12 57 86 33 92
Observe que después del primer paso, el elemento mayor (en este caso 92) está en la
posición correcta dentro del arreglo. En general x[n-i] estará en su posición correcta
después de la iteración i. El método se lama ordenamiento de burbuja porque cada
número “burbujea” con lentitud hacia su posición correcta. El conjunto completo de
iteraciones es:
iteración 0 : 25 57 48 37 12 92 86 33
iteración 1: 25 48 37 12 57 86 33 92
iteración 2: 25 37 12 48 57 33 86 92
iteración 3: 25 12 37 48 33 57 86 92
iteración 4: 12 25 37 33 48 57 89 92
iteración 5: 12 25 33 37 48 57 89 92
Ejemplo del Método de Ordenamiento Burbuja en C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Burbuja
class Burbuja
private int[] vector;
public void Cargar()
Console.WriteLine("Metodo de Burbuja");
Console.Write("Cuantos longitud del vector: ");
string linea;
linea = Console.ReadLine();
int cant;
cant = int.Parse(linea);
vector = new int[cant];
for (int f = 0; f < vector.Length; f++)
Console.Write("Ingrese elemento "+(f+1)+": ");
linea = Console.ReadLine();
vector[f] = int.Parse(linea);
public void MetodoBurbuja()
int t;
for (int a = 1; a < vector.Length; a++)
for (int b = vector.Length - 1; b >= a; b--)
if (vector[b - 1] > vector[b])
t = vector[b - 1];
vector[b - 1] = vector[b];
vector[b] = t;
}
}
public void Imprimir()
Console.WriteLine("Vector ordenados en forma ascendente");
for (int f = 0; f < vector.Length; f++)
Console.Write(vector[f]+" ");
Console.ReadKey();
static void Main(string[] args)
Burbuja pv = new Burbuja();
pv.Cargar();
pv.MetodoBurbuja();
pv.Imprimir();
Al ejecutar el código muestra el siguiente resultado
Método de Ordenamiento Quick Sort en C#
El método de ordenamiento Quick Sort es actualmente el más eficiente y veloz de los
métodos de ordenación interna. Es también conocido con el nombre del método rápido
y de ordenamiento por partición, en el mundo de habla hispana.
Este método es una mejora sustancial del método de intercambio directo y recibe el
nombre de Quick Sort por la velocidad con que ordena los elementos del arreglo. Su
autor C.A. Hoare lo bautizó así.
La idea central de este algoritmo consiste en los siguiente:
Se toma un elemento x de una posición cualquiera del arreglo.
Se trata de ubicar a x en la posición correcta del arreglo, de tal forma que todos
los elementos que se encuentran a su izquierda sean menores o iguales a x y
todos los elementos que se encuentren a su derecha sean mayores o iguales a
x.
Se repiten los pasos anteriores pero ahora para los conjuntos de datos que se
encuentran a la izquierda y a la derecha de la posición correcta de x en el
arreglo.
Ejemplo:
A: 15,67,08,16,44,27,12,35
Se selecciona A[i] x=15
Primera pasada (DER-IZQ)
A[8] >= x 35 >= 15 No hay intercambio
A[7] >= x 12 >= 15 Si hay intercambio
A: 12,67,08,16,44,27,15,35
(IZQ-DER)
A[2] < = X 67 < = 15 Si hay intercambio
A:12,15,08,16,44,27,67,35
2da. Pasada (DER-IZQ)
A[6] >= x 27 >= 15 No hay intercambio
A[5] >= x 44 >= 15 No hay intercambio
A[4] >= x 16 >= 15 No hay intercambio
A[3] >= x 08 >= 15 Si hay intercambio
A: 12,08,15,16,44,27,67,35
Como el recorrido de izquierda a derecha debería iniciarse en la misma posición donde
se encuentra el elemento x, el proceso se termina ya que el elemento x, se encuentra
en la posición correcta.
A: 12, 08, 15, 16, 44, 27, 67, 35
1er 2do Conjunto
16, 44, 27, 67, 35
x16
(DER-IZQ)
A[8]>=x No hay intercambio
A[7]>=x No hay intercambio
A[6]>=x No hay intercambio
A[5]>=x No hay intercambio
A: 12, 08, 15, 16, 44, 27, 67, 35
xß44
(DER-IZQ)
A[8]>= x Si hay intercambio
A: 12, 08, 15, 16, 35, 27, 67, 44
(IZQ-DER)
A[6] < = x No hay intercambio
A[7] < = x Si hay intercambio
12, 08, 15, 16, 35, 27, 44, 67
12, 08, 15, 16, 35, 27, 44, 67
35, 27, 44, 67
xß35
(DER-IZQ)
A[8] >= x No hay intercambio
A[7] >= x No hay intercambio
A[6] >= x Si hay intercambio
12, 08, 15, 16, 27, 35, 44, 67
12,08
xß12
(DER-IZQ)
A[2]>=x Si hay intercambio
EL VECTOR ORDENADO:
08,12,15,16,27,35,44,67
Ejemplo del Método de Ordenamiento Quick Sort en C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace quicksort
class Class
static void Main()
int n;
Console.WriteLine("Metodo de Quick Sort");
Console.Write("Cuantos longitud del vector: ");
n = Int32.Parse(Console.ReadLine());
llenar b = new llenar(n);
class llenar
int h;
int[] vector;
public llenar(int n)
{
h = n;
vector = new int[h];
for (int i = 0; i < h; i++)
Console.Write("ingrese valor {0}: ", i + 1);
vector[i] = Int32.Parse(Console.ReadLine());
quicksort(vector, 0, h - 1);
mostrar();
private void quicksort(int[] vector, int primero, int ultimo)
int i, j, central;
double pivote;
central = (primero + ultimo) / 2;
pivote = vector[central];
i = primero;
j = ultimo;
do
while (vector[i] < pivote) i++;
while (vector[j] > pivote) j--;
if (i <= j)
int temp;
temp = vector[i];
vector[i] = vector[j];
vector[j] = temp;
i++;
j--;
} while (i <= j);
if (primero < j)
quicksort(vector, primero, j);
if (i < ultimo)
quicksort(vector, i, ultimo);
private void mostrar()
{
Console.WriteLine("Vector ordenados en forma ascendente");
for (int i = 0; i < h; i++)
Console.Write("{0} ", vector[i]);
Console.ReadLine();
Al ejecutar el código muestra el siguiente resultado
Método de Ordenamiento Shell Sort en C#
Es un algoritmo de ordenación interna muy sencillo pero muy ingenioso, basado en
comparaciones e intercambios, y con unos resultados radicalmente mejores que los
que se pueden obtener con el método de la burbuja, el des elección directa o el de
inserción directa.
Sin embargo, es necesario romper una lanza a favor del algoritmo ShellSort, ya que es
el mejor algoritmo de ordenación in-situ... es decir, el mejor de aquellos en los que la
cantidad de memoria adicional que necesita -aparte de los propios datos a ordenar,
claro está- es constante, sea cual sea la cantidad de datos a ordenar. El algoritmo de la
burbuja, el de selección directa, el de inserción directa y el de Shell son todos in-situ, y
éste último, el de Shell, es el que mejor resultados da, sin ninguna duda de todos ellos
y sus posibles variantes.
El ShellSort es una mejora del método de inserción directa que se utiliza cuando el
número de elementos a ordenar es grande. El método se denomina “shell” –en honor
de su inventor Donald Shell – y también método de inserción con incrementos
decrecientes.
En el método de clasificación por inserción, cada elemento se compara con los
elementos contiguos de su izquierda, uno tras otro. Si el elemento a insertar es más
pequeño - por ejemplo -, hay que ejecutar muchas comparaciones antes de colocarlo
en su lugar definitivamente. Shell modifico los saltos contiguos resultantes de las
comparaciones por saltos de mayor tamaño y con eso se conseguía la clasificación
más rápida. El método se basa en fijar el tamaño de los saltos constantes, pero de más
de una posición.
Considere un valor pequeño que está inicialmente almacenado en el final del vector.
Usando un ordenamiento O(n2) como el ordenamiento de burbuja o el ordenamiento
por inserción, tomará aproximadamente n comparaciones e intercambios para mover
este valor hacia el otro extremo del vector. El Shell sort primero mueve los valores
usando tamaños de espacio gigantes, de manera que un valor pequeño se moverá
bastantes posiciones hacia su posición final, con sólo unas pocas comparaciones e
intercambios.
Uno puede visualizar el algoritmo Shell sort de la siguiente manera: coloque la lista en
una tabla y ordene las columnas (usando un ordenamiento por inserción). Repita este
proceso, cada vez con un número menor de columnas más largas. Al final, la tabla
tiene sólo una columna.
Mientras que transformar la lista en una tabla hace más fácil visualizarlo, el algoritmo
propiamente hace su ordenamiento en contexto (incrementando el índice por el tamaño
de paso, esto es usando i += tamaño_de_paso en vez de i++).
Por ejemplo, considere una lista de números como [ 13 14 94 33 82 25 59 94 65 23 45
27 73 25 39 10 ]. Si comenzamos con un tamaño de paso de 8, podríamos visualizar
esto dividiendo la lista de números en una tabla con 5 columnas. Esto quedaría así:
13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10
Entonces ordenamos cada columna, lo que nos da:
10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45
Cuando lo leemos de nuevo como una única lista de números, obtenemos:
[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ]
Aquí, el 10 que estaba en el extremo final, se ha movido hasta el extremo inicial. Esta
lista es entonces de nuevo ordenada usando un ordenamiento con un espacio de 3
posiciones, y después un ordenamiento con un espacio de 1 posición (ordenamiento
por inserción simple).
El Shell sort lleva este nombre en honor a su inventor, Donald Shell, que lo publicó en
1959. Algunos libros de texto y referencias antiguas le llaman ordenación "Shell-
Metzner" por Marlene Metzner Norton, pero según Metzner, "No tengo nada que ver
con el algoritmo de ordenamiento, y mi nombre nunca debe adjuntarse a éste."
Ejemplo del Método de Ordenamiento Shell Sort en C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PruebaVector
class PruebaVector
{
private int[] vector;
public void Cargar()
Console.WriteLine("Metodo de Shell Sort");
Console.Write("Cuantos longitud del vector:");
string linea;
linea = Console.ReadLine();
int cant;
cant = int.Parse(linea);
vector = new int[cant];
for (int f = 0; f < vector.Length; f++)
Console.Write("Ingrese elemento "+(f+1)+": ");
linea = Console.ReadLine();
vector[f] = int.Parse(linea);
public void Shell()
int salto = 0;
int sw = 0;
int auxi = 0;
int e = 0;
salto = vector.Length / 2;
while (salto > 0)
sw = 1;
while (sw != 0)
sw = 0;
e = 1;
while (e <= (vector.Length - salto))
if (vector[e - 1] > vector[(e - 1) + salto])
auxi = vector[(e - 1) + salto];
vector[(e - 1) + salto] = vector[e - 1];
vector[(e - 1)] = auxi;
sw = 1;
e++;
}
salto = salto / 2;
public void Imprimir()
Console.WriteLine("Vector ordenados en forma ascendente");
for (int f = 0; f < vector.Length; f++)
Console.Write(vector[f]+" ");
Console.ReadKey();
static void Main(string[] args)
PruebaVector pv = new PruebaVector();
pv.Cargar();
pv.Shell();
pv.Imprimir();
}
}
Al ejecutar el código muestra el siguiente resultado
Método de Ordenamiento de Inserción Binaria en C#
La Inserción Binaria, es una mejora de la Inserción Directa.
La Inserción Binaria es un método de inserción, que difiere de la Inserción Directa
simplemente en la búsqueda de la posición de la Inserción.
Veamos un ejemplo de como funciona este método de ordenamiento de Inserción
Binaria, analizando paso a paso.
1. Hallamos el elemento central del área comprendida por la parte ordenada más la
posición del elemento a insertar.
2. Comparamos el elemento central con el elemento que queremos insertar. Si
dicho elemento central es menor o igual, nos quedamos con la parte derecha
(Sin incluir el elemento central). En caso contrario, nos quedamos con la parte
izquierda incluyendo al elemento central.
3. Repetimos el mismo proceso sobre el área con la que nos quedamos, hasta que
dicha área sea nula.
4. Cuando el área sea nula, tendremos la posición de inserción.
Un ejemplo de método de inserción binaria en C#
int auxiliar;
int q;
int izqui;
int dere;
for (int i = 0; i < numeros.Length; i++)
{
auxiliar = numeros[i];
izqui = 0;
dere = i - 1;
while (izqui <= dere)
{
q = ((izqui + dere) / 2);
if (auxiliar < numeros[q])
{
dere = q - 1;
}
else
{
izqui = q + 1;
}
j = i - 1;
while (j >= izqui)
{
numeros[j + 1] = numeros[j];
j = j - 1;
}
numeros[izqui] = auxiliar;
}
}
for (int i = 0; i < longitud; i++)
Console.WriteLine(" " + numeros[i]);
Método de Ordenamiento de Inserción Directa en C#
El método de inserción directa es el que generalmente utilizan los jugadores de
cartas cuando ordenan éstas, de ahí que también se conozca con el nombre de
método de la baraja.
La idea central de este algoritmo consiste en insertar un elemento del arreglo en
la parte izquierda del mismo, que ya se encuentra ordenada. Este proceso se
repite desde el segundo hasta el n-esimo elemento.
Ejemplo:
Se desean ordenarse las siguientes clave del arreglo A: 15, 67, 08, 16, 44, 27,
12, 35
Primera pasada
A[2] < A[1] 67 < 15 No hay intercambio
A: 15, 67, 08, 16, 44, 27, 12, 35
Segunda pasada
A[3] < A[2] 08 < 67 Si hay intercambio
A[2] < A[1] 08 < 15 Si hay
A: 15, 08, 67, 16, 44, 27, 12, 35
Tercera pasada
A[4] < A[3] 08 < 15 Si hay intercambio
A[3] < A[2] 08 < 15 Si hay intercambio
A= 08, 15, 67, 16, 44, 27, 12, 35
Hasta la séptima pasada el arreglo queda ordenado: 08, 12, 15, 16, 27, 35, 44,
67
Ejemplo del Método de Ordenamiento Inserción Directa en c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PruebaVector
{
class PruebaVector
{
private int[] vector;
public void Cargar()
{
Console.WriteLine("Metodo de insercion directa");
Console.Write("Cuantos longitud del vector:");
string linea;
linea = Console.ReadLine();
int cant;
cant = int.Parse(linea);
vector = new int[cant];
for (int f = 0; f < vector.Length; f++)
{
Console.Write("Ingrese elemento "+(f+1)+": ");
linea = Console.ReadLine();
vector[f] = int.Parse(linea);
}
}
public void InsercionDirecta()
{
int auxili;
int j;
for (int i = 0; i < vector.Length; i++)
{
auxili = vector[i];
j = i - 1;
while (j >= 0 && vector[j] > auxili)
{
vector[j + 1] = vector[j];
j--;
}
vector[j + 1] = auxili;
}
}
public void Imprimir()
{
Console.WriteLine("Vector ordenados en forma ascendente");
for (int f = 0; f < vector.Length; f++)
{
Console.Write(vector[f]+" ");
}
Console.ReadKey();
}
static void Main(string[] args)
{
PruebaVector pv = new PruebaVector();
pv.Cargar();
pv.InsercionDirecta();
pv.Imprimir();
}
}
}
Al ejecutar el código muestra el siguiente resultado