Clasificación de series de clasificación de burbujas de algoritmo y prueba de rendimiento

Primer vistazo a la clasificación de burbujas

Los algoritmos de clasificación se utilizan a menudo como una práctica introductoria para el aprendizaje de algoritmos, y la clasificación de burbujas es el más simple de ellos. Nuestro tema de hoy es la clasificación de burbujas. Su idea básica es tan simple como un pez haciendo burbujas.


Imagina que hay un pez en la parte inferior de la matriz. En cada ronda, escupe una burbuja. La burbuja flotará de un extremo a la otra de la matriz. Durante el proceso de flotación, la burbuja capturará la mayor parte de la matriz. matriz a ordenar. Muévala a la parte superior, y luego elimine este elemento de la parte de la matriz a ordenar .

En la siguiente ronda, elija el más grande de los elementos restantes para clasificar y use burbujas para flotar hacia la parte superior nuevamente. De esta forma, después de n rondas de burbujas. Descendiendo desde la parte superior de la matriz, el elemento más grande, el segundo elemento más grande y el tercer elemento más grande están en orden. La matriz completa está ordenada. Por supuesto, si desea invertir el orden, elija el elemento más pequeño en cada ronda Sólo empápese.

El proceso de una ronda de burbujeo consiste en encontrar el elemento más grande en la ronda de burbujeo comparando e intercambiando constantemente dos elementos adyacentes y moverlo hacia la parte superior.


El proceso específico es imaginar un puntero, y el elemento apuntado por el puntero se llama elemento actual . El puntero primero apunta al primer elemento y compara el tamaño entre el elemento actual y el elemento siguiente. Si el elemento actual es más grande que el elemento siguiente, el elemento actual y el elemento siguiente se intercambian. Y mueva el puntero hacia atrás una posición, continúe comparando con el siguiente elemento, hasta el último elemento. De esta manera, se completa la primera ronda de burbujeo. Después de la primera ronda de burbujeo, el elemento del extremo derecho es el más grande. En la segunda ronda de burbujeo, a partir del primer elemento, la comparación y el intercambio se llevan a cabo en secuencia, y la comparación continúa hasta el penúltimo elemento. Al final de la segunda ronda, el penúltimo elemento de la derecha es el segundo más grande ... Después de N rondas de burbujeo, toda la matriz se ordena de pequeña a grande

El diagrama es el siguiente

Suponga que va a ordenar por burbujas la siguiente matriz

Primer burbujeo

El puntero apunta primero al primer elemento, compara el elemento actual con el siguiente elemento y encuentra que 9 es mayor que 5, luego intercambia los dos

El puntero retrocede un lugar

Continúe comparando el tamaño del elemento actual y el siguiente elemento, encuentre que 9 es mayor que 7, cámbielo

El puntero continúa retrocediendo un poco, continúa comparando e intercambiando, y finalmente 9 se burbujea hacia el extremo derecho, y la primera ronda de burbuja termina

Comienza la segunda ronda de burbujeo, coloque el puntero en el primer elemento y comience a repetir el proceso de la primera ronda (tenga en cuenta que la segunda ronda solo necesita burbujear a la segunda a la última posición, porque después de cada ronda, el más a la derecha La longitud de la secuencia ordenada en el lado será 1 bit más largo)

Si se encuentra que 5 es menor que 7, no se intercambia. El puntero retrocede

Encontró que 7 es mayor que 3, cámbielo

El puntero retrocede

Se encuentra que 7 es mayor que 1, y el intercambio ... Finalmente, 8 se burbujea hacia el extremo derecho

Continúe hasta la tercera ronda, 7 se burbujea en el extremo derecho

En la cuarta ronda, 6 llega al extremo derecho

...

Finalmente, toda la matriz se ordena

De acuerdo con esta idea, escriba el código de la siguiente manera

public void bubbleSort(int[] array) {
    
    
	for (int i = array.length - 1; i >= 0; i--) {
    
    
		for (int j = 0; j < i; j++) {
    
    
			if (array[j] > array[j + 1]) {
    
    
				swap(array, j , j + 1);
			}
		}
	}
}
public void swap(int[] array,int i,int j) {
    
    
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

El bucle exterior comienza desde la última posición de la matriz y representa la posición final de cada ronda (la primera ronda de burbujeo se detiene en la última posición, la segunda ronda de burbujeo se detiene en la penúltima posición, y así sucesivamente). El bucle interior es una ronda de burbujeo.Cada ronda de burbujeo comienza desde la primera posición, se compara e intercambia secuencialmente con la siguiente posición y continúa hasta la posición de parada de la ronda de burbujeo. Por supuesto, el código anterior solo escribe la realización de la parte central y no es perfecto. Por ejemplo, en el bubbleSortmétodo, primero debe determinar si la arrayvariable está null, y en el swapmétodo, debe determinar arraysi lo está nully verificar si la isuma jestá fuera de los límites.

Ideas de optimización

Idea uno

De hecho, hay espacio para la optimización en la implementación del tipo de burbuja anterior. Por ejemplo, si no hay intercambio de elementos en una determinada ronda de burbujeo. Esto significa que la matriz ya está ordenada como un todo y no hay necesidad de rondas de burbujeo posteriores. Modifique el código, justo antes del inicio de cada burbujeo de ronda, agregue una variable de bandera booleana boolean sorted = true, siempre que se produzca el burbujeo de ronda del elemento de conmutación, será sortedvariable a false. Entonces, dado que después del final de cada ronda burbujeante, agregue un juicio lógico, si el juicio sortedes true, la terminación anticipada del tipo, escriba el código a continuación.

public void bubbleSortV1(int[] array) {
    
    
    boolean sorted;
	for (int i = array.length - 1; i >= 0; i--) {
    
    
        sorted = true;
		for (int j = 0; j < i; j++) {
    
    
			if (array[j] > array[j + 1]) {
    
    
				swap(array, j , j + 1);
                sorted = false;
			}
		}
        if(sorted) {
    
    
            break;
        }
	}
}

Idea dos

Si lo anterior es la optimización con una granularidad mayor (optimización global para el ciclo externo, todo el proceso finaliza antes de tiempo cuando se cumplen las condiciones), todavía hay espacio para la optimización con una granularidad menor (optimización durante cada ronda de burbujeo). En la implementación original, después de cada ronda de burbujeo, la longitud de la secuencia ordenada más a la derecha se incrementa en uno. Es decir, la primera ronda de burbujeo debe intercambiarse y compararse hasta la última posición; la segunda ronda de burbujeo debe intercambiarse y compararse hasta la penúltima posición ... Sin embargo, cada ronda de burbujeo solo necesita hacer flotar las burbujas para una secuencia ordenada El límite puede terminarse y podemos decidir la posición de parada de la siguiente ronda de burbujeo de acuerdo con la situación real de cada ronda. En lugar de tener que llegar a una posición de parada fija en cada ronda.

Por ejemplo, la siguiente matriz

Después de la primera ronda de burbujeo, la matriz se convierte en

La última vez que se intercambiaron las posiciones fueron las posiciones de 3 y 4. Después de eso, solo se compararon y no se intercambiaron , lo que indica que las posiciones después de 4 eran todas secuencias ordenadas. Entonces, la posición final de la segunda ronda de burbujeo no tiene que ser la penúltima posición, sino que solo puede ir a la posición del último intercambio que ocurrió en la ronda anterior de burbujeo (a la derecha de la posición donde se produjo el último intercambio ocurrido, es decir, hay Secuencia). Es decir, para cada ronda de burbujeo, se agrega una nueva variable para registrar la posición donde ocurrió el último intercambio para indicar la posición final de la siguiente ronda de burbujeo. Escriba el código de la siguiente manera

public void bubbleSortV2(int[] array) {
    
    
	boolean sorted;
	int sortedSequenceBorder = array.length - 1;
	while (true) {
    
    
		sorted = true;
		int lastSwapPos = 0;
		for (int i = 0 ; i < sortedSequenceBorder; i++) {
    
    
			if (array[i] > array[i + 1]) {
    
    
				swap(array, i, i + 1);
				sorted = false;
				lastSwapPos = i;
			}
		}
		if (sorted) {
    
    
			break;
		}
		sortedSequenceBorder = lastSwapPos;
	}
}

Tenga en cuenta que no importa qué tan optimizado esté, el número de intercambios de elementos para la clasificación de burbujas no cambia, las medidas de optimización solo reducen el número de comparaciones innecesarias. Se proporcionan los siguientes ejemplos y usted mismo puede verificar

Pruebas de rendimiento

En teoría, debido a la introducción de medidas de optimización para los dos últimos, la eficiencia debería ser mayor que la de la versión no optimizada, es decir, la eficiencia debería ser

bubbleSortV2 > bubbleSortV1 > bubbleSort

Sin embargo, en las pruebas reales, se encuentra que a veces este no es el caso, porque las medidas de optimización agregan juicios adicionales durante cada ronda de burbujeo, lo que requiere una cierta cantidad de rendimiento, y si la matriz se va a ordenar, use medidas de optimización para Reducir el rendimiento de comparación inútil El costo es menor que el costo de rendimiento causado por la introducción de juicios adicionales, es decir, cuando el beneficio es menor que el costo, el rendimiento de V1 y V2 no necesariamente tiene que ser mayor que la versión no optimizada (y también es necesario considerar la situación real de la máquina en tiempo de ejecución). Sin embargo, cuando el tamaño de la matriz es grande, las medidas de optimización pueden reducir más el número de comparaciones y el beneficio es mayor, y el rendimiento será mejor que la versión no optimizada.

La siguiente es una prueba de rendimiento para las tres versiones de clasificación de burbujas. La prueba utiliza una matriz generada aleatoriamente, el tamaño de la matriz varía de 100, 400, 700 ... a 14800 (el tamaño de la matriz comienza desde 100 y el tamaño aumenta secuencialmente en 300, se prueban un total de 50 conjuntos de matrices ). Para evitar los factores de influencia de la máquina en tiempo de ejecución, la prueba se repite 20 veces para cada grupo de matrices y se toma el rendimiento promedio. El gráfico de líneas de rendimiento dibujado es el siguiente

Se puede ver que a medida que aumenta el tamaño de la matriz, el rendimiento de la versión optimizada es significativamente mejor que el de la versión no optimizada, y el rendimiento de la versión V2 es ligeramente mejor que el de la V1.

Expandir

Además, existe una variante de clasificación burbujeante llamada clasificación cóctel . Su idea es burbujeo bidireccional. Las rondas impares son de izquierda a derecha, y el elemento más grande se burbujea en el extremo derecho, y las rondas pares son de derecha a izquierda. El elemento más pequeño burbujea en el extremo izquierdo. La clasificación de cócteles se ordena en el medio de la matriz y, cuando los dos extremos están desordenados, se puede mejorar el rendimiento. La siguiente es su implementación de código, muy similar a la clasificación de burbujas

	public void cockTailSort(int[] array) {
    
    
		boolean moveRight = true;
		int rightBorder = array.length - 1;
		int leftBorder = 0;
		boolean sorted = false;
		while (!sorted) {
    
    
			sorted = true;
			if (moveRight) {
    
    
				for (int i = leftBorder; i < rightBorder; i++) {
    
    
					if (array[i] > array[i + 1]) {
    
    
						swap(array, i, i + 1);
						sorted = false;
					}
				}
				rightBorder--;
				moveRight = false;
			} else {
    
    
				for (int i = rightBorder; i > leftBorder; i--) {
    
    
					if (array[i] < array[i - 1]) {
    
    
						swap(array, i, i - 1);
						sorted = false;
					}
				}
				leftBorder++;
				moveRight = true;
			}
		}
	}

Incorpore la clasificación de cócteles en la prueba de rendimiento para ver cómo se compara con la clasificación de burbujeo normal

Se puede ver que el rendimiento de la clasificación de cócteles es ligeramente mejor que la clasificación de burbujeo ordinaria

Supongo que te gusta

Origin blog.csdn.net/vcj1009784814/article/details/109000707
Recomendado
Clasificación