Tecnología

Inicio

Cómo utilizar un heapsort en Java

El algoritmo heapsort es uno de los algoritmos de clasificación más rápida disponibles. Los programadores usan heapsort en Java porque es una buena opción para matrices muy grandes que saben que es en un estado sin clasificar. Por razones de eficacia, no se utiliza una estructura de árbol real. En cambio, el árbol se forma en el lugar, justo en la matriz. El algoritmo es un heapsort "en su lugar" algoritmo, ya que no requiere más memoria para realizar la clasificación.

Instrucciones

1 Componer el método de intercambio. Esto intercambiar dos elementos de una matriz. ""public static void swap(int[] a, int i, int j) {
int tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}""
""public static void swap(int[] a, int i, int j) {
int tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}""

2 Escribe el núcleo del algoritmo, el método siftDown. Se utiliza tanto para formar la estructura de pila y hacer el tipo real.

3 Tamizar valores grandes hacia la raíz de los valores de los árboles y pequeñas hacia las hojas con el método siftDown. Como este método se llama varias veces durante el proceso de clasificación, el nodo más grande se tamiza consistentemente al nodo raíz y se trasladó a la final de la matriz. Cualquier nodo n tiene un máximo de dos niños, cuyos índices son n

2 + 1 y n + 2 2. ""public static void siftDown(int[] a, int start, int end) {
int root = start;

while( root 2 + 1 <= end ) {
int child = root
2 + 1;

// If the child has a sibling and the child's value is less than its sibling
if( child < end && a[child] < a[child + 1] ) {
child++;
}

if( a[root] < a[child] ) {
swap(a, root, child);
root = child;
} else {
return;
}
}
}""
""public static void siftDown(int[] a, int start, int end) {
int root = start;

while( root 2 + 1 <= end ) {
int child = root
2 + 1;

// If the child has a sibling and the child's value is less than its sibling
if( child < end && a[child] < a[child + 1] ) {
child++;
}

if( a[root] < a[child] ) {
swap(a, root, child);
root = child;
} else {
return;
}
}
}""

4 Utilice el método heapify. Este método se llama al principio de la clase para crear la estructura inicial del almacenamiento dinámico. Esto se realiza de forma rápida, ya que la estructura del montón es un tanto vaga. El único requisito es que cada nodo raíz debe ser mayor que los nodos secundarios. ""public static void heapify(int[] a) {
for( int start = a.length / 2--1; start >= 0; start-- )
siftDown(a, start, a.length-1);
}""
""public static void heapify(int[] a) {
for( int start = a.length / 2--1; start >= 0; start-- )
siftDown(a, start, a.length-1);
}""


5 Escribe el método HeapSort. El método heapifies primero la matriz para prepararse para la especie. El método siftDown continuación, se llama de nuevo desde el nodo raíz es ahora un valor pequeño. Este tamiza a un nuevo valor grande para el nodo raíz, y todo el proceso se repite hasta que el tamaño de la pila es uno. ""public static void heapSort(int[] a) {
heapify(a);

for( int end = a.length--1; end > 1; end--) {
swap(a, end, 0);
siftDown(a, 0, end--1);
}
}""
""public static void heapSort(int[] a) {
heapify(a);

for( int end = a.length--1; end > 1; end--) {
swap(a, end, 0);
siftDown(a, 0, end--1);
}
}""

6 Probar el método HeapSort. El siguiente ejemplo muestra un pequeño programa de prueba. ""public static void main(String[] args) {
int[] a = new int[10];

for( int i = 0; i < 10; ++i ) a[i] = i+1;
for( int i = 0; i < 10; ++i )
swap(a, i, i + (int) (Math.random() * (9--i)));

System.out.println("Before sorting:");
for( int i = 0; i < a.length; ++i ) System.out.println(a[i]);

heapSort(a);
System.out.println("After sorting");
for( int i = 0; i < a.length; ++i ) System.out.println(a[i]);
}""
""public static void main(String[] args) {
int[] a = new int[10];

for( int i = 0; i < 10; ++i ) a[i] = i+1;
for( int i = 0; i < 10; ++i )
swap(a, i, i + (int) (Math.random() * (9--i)));

System.out.println("Before sorting:");
for( int i = 0; i < a.length; ++i ) System.out.println(a[i]);

heapSort(a);
System.out.println("After sorting");
for( int i = 0; i < a.length; ++i ) System.out.println(a[i]);
}""

Consejos y advertencias

  • Aunque heapsort no se utiliza tan a menudo en Java como quicksort (quicksort porque es, en promedio, más rápido), el heapsort tiene un escenario peor de los casos más rápido. Donde peor de los casos de la ordenación rápida es O (n ^ 2), peor de los casos de heapsort es O (n
  • log (n)).
  • Dado que el método siftDown tamiza los valores más grandes en la parte superior de la pila (índice de matriz 0), en cada iteración del tipo del nodo raíz se intercambia con el último nodo de hoja, y el tamaño de la pila se decrementa. Se trata de cómo se realiza la clasificación real, tamizar los valores grandes de la parte superior y moverlos hasta el final.
  • El uso de una estructura de árbol real generaría una gran cantidad de nuevos objetos, poner la carga en el colector y asignador de basura, utilizar más memoria y tener más acceso a memoria.