Algoritmo de clasificación simple, bisección y logaritmo

Algoritmo de clasificación simple, bisección y logaritmo

clasificación de selección

Por primera vez, se selecciona el elemento más pequeño (o más grande) de los elementos de datos que se van a clasificar y se almacena al comienzo de la secuencia, y luego se encuentra el elemento más pequeño (más grande) de los elementos restantes sin clasificar y luego se coloca en el El final de la secuencia ordenada. Y así sucesivamente, hasta que el número de todos los elementos de datos a ordenar sea cero.

código :

/**
 * 选择排序
 */
public static void selectionSort(int[] arr){
    // 如果数组为空或只有一个元素故不需要进行排序,直接返回即可
    if(arr == null || arr.length < 2 ){
        return;
    }
    for(int i = 0; i < arr.length -1;i++ ){ // 从i~N-1中找出最小的元素并放到i位置上
        int minIndex = i;
        for(int j = i+1;j < arr.length;j++){ //从i~N-1上找最小值的下标
            minIndex = arr[j] < arr[minIndex]? j : minIndex;
        }
        swap(arr,i,minIndex);
    }
}

// 交换arr的i和j位置上的值
private static void swap(int[] arr, int i, int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

Ordenamiento de burbuja

Visite repetidamente la columna de elementos que desea ordenar, compare dos elementos adyacentes a su vez e intercámbielos si el orden (como de mayor a menor, letra inicial de Z a A) es incorrecto. El trabajo de visita de elementos se repite hasta que no es necesario intercambiar elementos contiguos, es decir, se ha ordenado la columna de elementos.

/**
 * 冒泡排序
 */
public static void bubbleSort(int[] arr){
    // 数组为空或数组元素为1则不需要进行排序,直接推出即可
    if(arr == null || arr.length<2){
        return;
    }
    for(int i = 0; i < arr.length-1; i++){ // 控制比较轮次,一共 n-1 趟
        for (int j = 0; j < arr.length-1-i; j++){ // 控制两个挨着的元素进行比较
            if(arr[i] > arr[j]){
                swap(arr,arr[i],arr[j]);
            }
        }
    }
}
// 交换arr的i和j位置上的值  ^ 表示异或运算,不同为1相同为0
// 数组中这样交换两个数的前提是 i j 位置上的数一定不相同 否则i j 位置上的数均会变成0
// 不提倡这么写!!!
private static void swap(int[] arr, int i, int j) {
	arr[i] = arr[i] ^ arr[j];
	arr[j] = arr[i] ^ arr[j];
	arr[i] = arr[i] ^ arr[j];
}

Suplemento: No aplica para espacio adicional para canjear el valor de dos números

¡La premisa aquí es que ayb son dos áreas separadas en la memoria!
inserte la descripción de la imagen aquí

Suplemento: preguntas de la entrevista XOR

Hay n tipos de números en una matriz arr

1. Un tipo de número aparece un número impar de veces, y otros números aparecen un número par de veces, ¿cómo averiguar el número que aparece un número impar de veces?

2. Los dos números pueden aparecer un número impar de veces, y los otros números pueden aparecer un número par de veces ¿Cómo saber el número que aparece un número impar de veces?

desatar:

  1. Establezca una variable en ero ero=Todos los elementos en la matriz son XORed ero=Un número que aparece un número impar de veces

Debido a que la operación XOR satisface las leyes conmutativa y asociativa, el mismo es 0, el resultado XOR de un número par de números es 0, y cualquier número y 0 XOR es igual a sí mismo. (Similar a Xiaoxiaole)

  1. Establecer una variable como ero Sean a y b números que aparecen un número impar de veces

a^b != 0 significa que a y b tienen al menos un bit diferente, asumiendo que el octavo bit es diferente. Divida todos los números en dos categorías, los números con 1 en el 8° dígito y 0 en el 8° dígito (los números que aparecen un número par de veces también se clasificarán de esta manera), y a y b solo ocuparán un lado de ellos. eor1 a XOR el número cuyo octavo dígito es 1, y el número que aparece un número par de veces aún no se altera y se borra en 0. En este momento, eor1 obtiene a o b. En este momento, el otro número en a y b se obtiene con ero^ero1!

/**
 * 异或运算面试题 第二问
 */
public static void printOddTimesNum2(int[] arr){
    int eor = 0;
    for(int i : arr){
        eor ^= i;
    }
    // eor = a ^ b
    // eor != 0
    // eor必然有一个位置上是1 选择最右侧的数值为1
    // 将一个不为0的数最右侧的1提取出来  ~eor 表示 eor取反
    int rightOne = eor & (~eor + 1); // 也就是说  一个数 & 自身取反+1 则把自己最右侧的数给弄出来了

    int onlyOne = 0; // eor1
    for(int cur : arr){
        if((cur & rightOne) == 1){ //那个位置 等于 1 我才进行异或  相当于两边只要了一侧
            onlyOne ^= cur;
        }
    }

    System.out.println("两个出现了奇数次的数为: "+ onlyOne + " " + (eor ^ onlyOne));

}

tipo de inserción

Se refiere a los elementos que se ordenarán, asumiendo que los números n-1 anteriores (donde n>=2) se han ordenado, ahora inserte el número n en la secuencia previamente ordenada y luego encuentre la posición adecuada, de modo que la secuencia insertado en el número n también se ordena. De acuerdo con este método, todos los elementos se insertan hasta que se ordena la secuencia completa, lo que se denomina ordenación por inserción. La clasificación por inserción es equivalente a garantizar que el primer elemento esté en orden, los primeros 2 elementos estén en orden, los primeros 3 elementos estén en orden y los primeros 4 elementos estén en orden...

/**
 * 插入排序(优于选择排序和冒泡排序)
 */
public static void insertSort(int[] arr){
    if(arr == null || arr.length < 2){
        return;
    }
    for (int i = 1; i < arr.length; i++) { // 0到i做到有序
        for(int j = i-1 ; j >= 0 && arr[j] > arr[j + 1]; j--){
            swap(arr,i,j+1);
        }
    }
}

dicotomía

Primero, suponiendo que los elementos de la tabla están dispuestos en orden ascendente, compare la clave registrada en la posición media de la tabla con la clave de búsqueda, si las dos son iguales, la búsqueda es exitosa; de lo contrario, use el registro de la posición media para Divida la tabla en dos subtablas, si la clave registrada en la posición media es mayor que la clave de búsqueda, se busca más en la subtabla anterior; de lo contrario, se busca más en la última subtabla. Repita el proceso anterior hasta que se encuentre un registro que cumpla con la condición, haciendo que la búsqueda sea exitosa, o hasta que la tabla secundaria no exista, en este momento la búsqueda no tiene éxito.

  1. Encuentra si un cierto número existe en una matriz ordenada

Complejidad temporal O(LogN)

  1. En una matriz ordenada, encuentra la posición más a la izquierda de >= cierto número

Por ejemplo: encontrar el número más a la izquierda de 1 2 2 2 2 2 3 3 3 3 4 4 4 4 4 5 5 5 5 5 5 >=3?

La diferencia entre este y el primer punto es que para encontrar si un número existe por dos puntos, solo necesitas encontrarlo, pero para encontrar un número en el lado más a la izquierda, ¡necesitas llevar a cabo dos puntos todo el tiempo!

  1. problema mínimo local

Por ejemplo: los elementos en la matriz arr están desordenados, dos números adyacentes cualesquiera no son iguales, encuentre un número mínimo local y la complejidad del tiempo es menor que O(n).

Mínimo local: i-1 i i+1 Si el número en la posición i en la matriz es menor que el número en i-1 y menor que el número en i+1, i se llama el número mínimo local.

0 1 2 … M-1 M M+1 …N-2 N-1

Encuentre M en la primera dicotomía y devuelva M si M es menor que el número de M-1 y menor que el número de M-2. De lo contrario, si continúa buscando desde un lado, ¡definitivamente encontrará una posición mínima local!

El concepto y uso de logaritmos.

  1. Hay un método que desea probar un
  2. La complejidad de implementación no es buena pero el método b es fácil de implementar
  3. Implementar un generador de muestras aleatorias
  4. Ejecute el método a y el método b en la misma muestra aleatoria para ver si los resultados son los mismos.
  5. Si hay una muestra aleatoria que hace que los resultados de la comparación sean inconsistentes, imprima la muestra para intervención manual y cambie al método a o al método b
  6. Cuando el número de muestras es grande, la prueba de comparación sigue siendo correcta y se puede determinar que el método a es correcto.

Como su nombre lo indica, el logaritmo es una herramienta para comparar datos. Generalmente, la prueba de comparación de datos se realiza en un entorno libre de OJ, que puede realizar la prueba de sus propios datos sin depender de la plataforma en línea. Por ejemplo, hay dos métodos: el método a (quiero probar) y el método b (muy simple pero no eficiente).Utilizas un generador de muestras aleatorias para generar una serie de datos y comparas los datos generados por el método a con los datos generados. por el método b., si los datos son inconsistentes, significa que uno de los métodos tiene un error, y si son consistentes, significa que el método es correcto. Este es el principio del logaritmo .

/**
 * 生成随机数组
 */
public static int[] generateRandomArray(int maxSize,int maxValue){

    // Math.random() -> [0,1) 所有的小数,等概率返回一个
    // Math.random() * N -> [0,N) 所有小数等概率返回一个
    // (int)(Math.random() * N) -> [0,N-1] 所有的整数,等概率返回一个
    int[] arr = new int[(int) ((maxSize+1)*Math.random())]; // 数组长度随机
    for(int i = 0; i < arr.length; i++){
        arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());
    }

    return arr;
}

public static void main(String[] args) {
   // 对数器代码实现举例
   int testTime = 500000; // 表示测试的次数
   int maxSize = 100; // 确保了每次生成的数的大小范围在0~100之间
   int maxValue = 100; // 确保了每一次生成的数值是在0~100之间
   boolean succeed = true;
    for (int i = 0; i < testTime; i++) {
        int[] arr1 = generateRandomArray(maxSize,maxValue);
        int[] arr2 = copyArray(arr1); // 将数组arr1拷贝一份
        insertionSort(arr1);
        comparator(arr2);
        if(!isEqual(arr1,arr2)){
            succeed = false;
            break;
        }
    }
	system.out.println(succeed);
}

Supongo que te gusta

Origin blog.csdn.net/ailaohuyou211/article/details/127128452
Recomendado
Clasificación