Estructura de datos y algoritmo: dos formas de implementar la clasificación de Hill

Fuente

Antes de explicar la clasificación de Hill, primero comprendamos el origen de la clasificación de Hill. De hecho, la clasificación de Hill también es una clasificación de inserción, es una clasificación de inserción avanzada que fue inventada por Great God Hill y optimizada para una clasificación de inserción simple . Es decir, el tipo Hill también es un tipo de inserción. Comprendamos los problemas de la clasificación simple.

Problemas con el tipo de inserción simple

Veamos los posibles problemas del tipo de inserción simple: la
matriz arr = {2,3,4,5,6,1} En este momento, el número 1 (mínimo) que debe insertarse, tal proceso es:
{2,3,4, 5,6,6}
{2,3,4,5,5,6}
{2,3,4,4,5,6}
{2,3,3,4,5,6}
{2,2, 3,4,5,6}
{1,2,3,4,5,6}
Conclusión: cuando el número a insertar es un número menor, el número de cambios hacia atrás aumenta significativamente, lo que tiene un impacto en la eficiencia.

La idea básica de la clasificación de Hill

¿Cómo se optimiza la clasificación de Hill? Es decir, cómo hacer que el número más pequeño en la clasificación de inserción se mueva a una posición adecuada después de un número menor de cambios hacia atrás.

Por favor, consulte la explicación profesional:

La ordenación en pendiente consiste en agrupar registros por un cierto incremento de subíndice y utilizar el algoritmo de ordenación por inserción directa para ordenar cada grupo; a medida que el incremento disminuye gradualmente, cada grupo contiene más y más palabras clave. Cuando el incremento disminuye a 1, Todo el archivo se divide en un grupo y el algoritmo termina

Si puedes entenderlo, eres increíble. De todos modos, no lo entendí. Aquí hay algunas imágenes de algoritmos para ayudarlo a comprender este algoritmo.

Inserte la descripción de la imagen aquí

En pocas palabras, se agrega algo llamado hueco a la clasificación de Hill. Su tamaño inicial es igual a la mitad de la longitud de la matriz y se reduce a la mitad en cada ciclo. Su función es agrupar la matriz, agrupar los elementos de la matriz en dos y realizar una ordenación por inserción, de modo que la operación de ordenación pueda completarse con el menor número de movimientos posible.

Realización concreta

Más tarde, llegamos a la implementación de código específico:

Supongamos que clasificamos el arreglo arr [8,9,1,7,2,3,5,4,6,0], Hill. De acuerdo con el conocimiento mencionado anteriormente.

  1. Primero determine si el incremento es mayor que 0
    2) Calcule el incremento = longitud de arr / 2 = 5
    3) Grupo 8-> 3, 9-> 5, 1->
    4, 7-> 6, 2-> 0 3) y Determine si necesita intercambiar posiciones en la
    primera ronda
//根据length/2 = 5 ,步长 = 5
		for(int i = 5; i<arr.length; i++) {
			//如果当前元素大于加上步长后的那个元素,说明交换
			for(int j=i-5;j>=0;j-=5) {
				if(arr[j] > arr[j+5]) {
					temp = arr[j];
					arr[j]=arr[j+5];
					arr[j+5]=temp;
				}
			}
		}
		System.out.println("希尔排序1轮后:"+Arrays.toString(arr));

Segunda ronda

//步长 = 5/2 =2
		for(int i = 2; i<arr.length; i++) {
			for(int j=i-2;j>=0;j-=2) {
				if(arr[j] > arr[j+2]) {
					temp = arr[j];
					arr[j]=arr[j+2];
					arr[j+2]=temp;
				}
			}
		}
		
		System.out.println("希尔排序2轮后:"+Arrays.toString(arr));

Tercera ronda

//步长 = 2/2 = 1
		for(int i = 1; i<arr.length; i++) {
			for(int j=i-1;j>=0;j-=1) {
				if(arr[j] > arr[j+1]) {
					temp = arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=temp;
				}
			}
		}
		
		System.out.println("希尔排序3轮后:"+Arrays.toString(arr));
		*/

Resultados en ejecución
Inserte la descripción de la imagen aquí
Aquí está mi código Java en elipse, demasiado flojo para volver a escribir python.

Aquí está el código de clasificación de Hill basado en el intercambio después de la integración de Python:

def shellSort(arr):
    temp = 0
    gap = len(arr)
    while gap>1:
        gap = int(gap/2)
        for i in range(gap,len(arr),1):
            for j in range(i-gap,-1,-gap):
                if arr[j]>arr[j+gap]:
                    temp = arr[j]
                    arr[j] = arr[j+gap]
                    arr[j+gap] = temp


Sin embargo, debido a que se intercambia el valor de dos elementos, similar al tipo de burbuja, la eficiencia de tiempo es muy baja. Por lo tanto, es necesario mejorar la operación de mover elementos a una posición adecuada e insertar elementos después de insertar la clasificación.

def shellSort2(arr):
    temp = 0
    gap = len(arr)
    while gap>1:
        gap = int(gap/2)
        for i in range(gap,len(arr),1):
            j = i
            temp = arr[j]
            if arr[j]<arr[j-gap]:
                #先移位
                while(j-gap>=0 and temp<arr[j-gap]):
                    arr[j] = arr[j-gap]
                    j -= gap
                #后插入
                arr[j] = temp

Este es un código de clasificación de Hill que utiliza ubicaciones de intercambio móvil. Ahora probemos si mejora la eficiencia del tiempo. Importe el tiempo y los módulos aleatorios para crear una matriz aleatoria con 8000 elementos. El código específico es el siguiente:

import time
import random

#arr = [8,9,1,7,2,3,5,4,6,0]

arr = [0 for i in range(8000)]
for i in range(8000):
    arr[i]=random.randint(0,8000)

def shellSort(arr):
    temp = 0
    gap = len(arr)
    while gap>1:
        gap = int(gap/2)
        for i in range(gap,len(arr),1):
            for j in range(i-gap,-1,-gap):
                if arr[j]>arr[j+gap]:
                    temp = arr[j]
                    arr[j] = arr[j+gap]
                    arr[j+gap] = temp


def shellSort2(arr):
    temp = 0
    gap = len(arr)
    while gap>1:
        gap = int(gap/2)
        for i in range(gap,len(arr),1):
            j = i
            temp = arr[j]
            if arr[j]<arr[j-gap]:
                #先移位
                while(j-gap>=0 and temp<arr[j-gap]):
                    arr[j] = arr[j-gap]
                    j -= gap
                #后插入
                arr[j] = temp
print("交换式希尔排序:")
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
shellSort(arr)
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
#print(arr)

print("插入式希尔排序:")
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
shellSort2(arr)
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
#print(arr)

Los resultados de la operación se muestran en la figura: se
Inserte la descripción de la imagen aquí
puede ver que la eficiencia del tiempo ha mejorado mucho, desde los 9 segundos originales hasta menos de 1 segundo. Ok, el intercambio ha terminado.

27 artículos originales publicados · elogiados 2 · visitas 680

Supongo que te gusta

Origin blog.csdn.net/qq_44273739/article/details/105243321
Recomendado
Clasificación