Algoritmo elemental (3): explicación e implementación de la dicotomía (lenguaje C) y la aplicación de la dicotomía en matrices ordenadas

Directorio de artículos de la serie

 Capítulo 1  Algoritmos elementales (1): comprensión de la complejidad del tiempo mediante algoritmos de clasificación simples

 Capítulo 2  Algoritmo preliminar (2): una introducción detallada a los detalles y la complejidad temporal de la clasificación por inserción

 Capítulo 3 Algoritmos elementales (3): Explicación e implementación de la dicotomía y la aplicación de la dicotomía en matrices ordenadas


Tabla de contenido

Directorio de artículos de la serie

prefacio

1. Explicación e implementación de la dicotomía (lenguaje C)

1.1 ¿Por qué utilizar la búsqueda binaria en una matriz ordenada?

1.2 Explicación de la búsqueda binaria:

 1.3 Implementación del código de dicotomía:

2. Aplicación de la dicotomía (no solo en matrices ordenadas)

2.1 Uso general

 2.2 Práctica no convencional (realizada en una matriz innecesaria)

Resumir


prefacio

       Vaya, es el tercer capítulo en un abrir y cerrar de ojos. En los dos primeros capítulos (si desea leer el contenido de los dos primeros capítulos, haga clic en el enlace de la serie de catálogos de artículos) , explicamos principalmente el algoritmo de clasificación . con una complejidad temporal de O (N ^ 2) ( clasificación de burbujas , clasificación de selección , clasificación de inserción ), no sé qué piensas.

       En este capítulo, hablamos principalmente sobre el uso del método de dicotomía y tres preguntas de programación sobre el método de dicotomía para romper con la idea de que el método de dicotomía solo se puede usar en matrices ordenadas .


1. Explicación e implementación de la dicotomía (lenguaje C)


1.1 ¿Por qué utilizar la búsqueda binaria en una matriz ordenada?


       Generalmente buscamos un número en una matriz ordenada , si buscamos uno por uno según la cantidad de datos , ¡a veces será muy rápido y otras veces muy lento! Esto es más problemático, por lo que no podemos usarlo uno por uno para encontrarlo.

       ¿Por qué a veces es rápido y a veces lento? Supongamos que ahora tenemos una matriz ordenada (1,2,3,4,5,6,7,8,9,10,11,12,13), si quieres encontrar 1 , solo necesitas atravesar Un bit es suficiente; pero si desea encontrar 13 , debe recorrer toda la matriz .

       En este punto, la matriz a buscar es una matriz ordenada , y podemos usar las características de las matrices ordenadas para usar la búsqueda binaria para encontrar el número que estamos buscando.


1.2 Explicación de la búsqueda binaria:


       En la introducción anterior, se dice que la búsqueda binaria se utiliza en una matriz ordenada, entonces, ¿ cómo se implementa la búsqueda binaria?

La idea básica de  la búsqueda binaria es: primero encuentre el número del medio y compárelo con el número a buscar , y luego divida la situación :

       1) Si es menor que el número a buscar, descarte la mitad izquierda del número , busque el número del medio en la mitad derecha del número y compárelo con el número a encontrar , y repita este proceso ;

       2) Si es mayor que el número a buscar, descarte la mitad derecha del número , busque el número del medio en la mitad izquierda del número y compárelo con el número a buscar , y repita este proceso ;

       Finalmente , hasta encontrar el último número .

       A continuación, estime la complejidad temporal de la búsqueda binaria y utilice los peores datos para el cálculo, porque la mitad de los números deben descartarse en un flujo de código , por lo que la complejidad temporal es O (logN) .


 1.3 Implementación del código de dicotomía:


       Después del análisis detallado anterior, el editor siente que los jueces han entendido completamente la idea de la dicotomía , así que a continuación, implementemos la dicotomía con el editor .

El código para implementar la dicotomía es el siguiente:

    int left = 0;
    int right = n - 1;
    while (left <= (right - 1)){     //判断条件是左边指向的位置大于右边指向的位置
        int mid = (left + right) / 2;//中点的位置要随时更新,以便求出最新的中点坐标
        if(k > arr[n - 1])      //如果要查找的数大于数组的最后一个数时,则不需要继续查找
            break;
        if (arr[mid] == k){
            right = mid;
            if(arr[mid - 1] < arr[mid])  //与中间数进行比较
                ans = mid;
        }
        if(arr[mid] > k)     //随时更新中点坐标
            right = mid;  
        if(arr[mid] < k)
            left = mid;
    }

2. Aplicación de la dicotomía (no solo en matrices ordenadas)


2.1 Uso general


       Arriba hemos buscado un determinado número en una matriz ordenada , a continuación escribiremos una variante: encontrar una determinada posición

Tema: Debe ingresar un n, un número k, y luego ingresar una matriz arr con una longitud de n tamaños, y luego necesita encontrar la posición más a la izquierda en arr que satisfaga >=K, y generar esta posición, si esto la posición no existe Solo genera -1.

      Al ver esta pregunta, mi primera reacción es atravesar la matriz ordenadasiempre que se encuentre que el primer número es igual a k, es la posición que estamos buscando , entonces este método es el mismo que el escrito arriba. Pensando como la primera pregunta , pero a veces muy lento. A veces muy rápidamente .

       En este artículo, hemos aprendido la dicotomía y debemos usarla para resolver problemas. La idea básica es: primero encuentre el número del medio y compárelo con el número que desea encontrar , y luego divida la situación :

       1) Si es menor que el número a buscar, la posición más a la izquierda de >=K debe estar a la derecha , luego descarta la mitad izquierda del número , encuentra el número del medio en la mitad derecha del número y compáralo con el número a buscar y repetir este proceso ;

       2) Si el número a buscar es igual o mayor que el número a buscar, la posición más a la izquierda de >=K debe estar a la derecha , luego descarta la mitad derecha del número , márcala si es igual a k y luego busque el número del medio en la mitad izquierda del número que coincida con el número a buscar. Se comparan los números y se repite este proceso ; finalmente, se recorre toda la matriz para encontrar el primer número marcado .

       Finalmente , hasta encontrar el último número >=K .

El código para implementar el tema es el siguiente:

int main()
{
	int n = 0, k = 0;
	scanf("%d %d", &n, &k);
	int a[1000000];
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	int left = 0;
	int right = n - 1;
	int mid = 0;
	int reslut = -1;    //因为如果找不到,就输出-1
	while (left <= right){
		mid = (left + right) / 2;
		if (a[mid] >= k){
			reslut = mid;
			right = mid - 1;
		}
		else
			left = mid + 1;
	}
	printf("%d\n", reslut);
	return 0;
}

 2.2 Práctica no convencional (realizada en una matriz innecesaria)


       ¿Puede la dicotomía realmente funcionar solo en matrices ordenadas? Después de que el editor se enteró de este tema, ¡yo también me quedé desconcertado! ¡La respuesta es sí!

       ¡A continuación, sigue los pasos del editor para aprender! Mire este tema: El problema del mínimo local .

El concepto de mínimo local: 1) El número en la posición 0 de la matriz es menor que el número en la posición 1 ;

                             2) El número enla posición N-1de la matrizmenorel número enla posición N-2;

                             3) El número enla i-ésima posiciónde la matrizmenorlos números enambos lados.

Pregunta: Dada una matriz desordenada arr, se sabe que dos números adyacentes cualesquiera en arr no son iguales, solo necesita devolver la posición donde ocurre cualquier mínimo local en arr y generar -1 si no existe tal posición.

       El editor puede analizar y obtener:

       Primero juzgue el número en la posición 0 y el número en la posición 1, y luego juzgue el número en la posición N-1 y el número en la posición N-2. Si ninguna de estas dos situaciones es cierta, entonces debe haber una disminución al principio y un aumento al final , y debido a que cada dos números en la matriz son diferentes, debe haber un mínimo local en 1 a N-2 .

       A continuación, podemos utilizar la dicotomía para descartar números. Encuentra el número en la posición media y compáralo con los números de ambos lados . Si ambos son menores que, devuelve el número en la posición media; si un lado no es menor que, descarta la mitad y continúa buscando en la otra mitad.

El código para implementar el tema es el siguiente:

int main() {
    int n = 0;
    scanf("%d", &n);
    int a[100000];
    for (int i = 0; i < n; i++) {
        scanf("%d", a + i);
    }
    int left = 0;
    int right = n - 1;
    int mid = -1;
    if (n == 1 || a[0] < a[1]) {
        printf("%d\n", 0);
        return 0;
    }
    else if (a[n - 1] < a[n - 2]) {
        printf("%d\n", n - 1);
        return 0;
    } else {
        while (left <= right) {
            mid = (left + right) / 2;

            if (a[mid] > a[mid - 1]) {
                right = mid - 1;
            }
            else if (a[mid] > a[mid + 1]) {
                left = mid + 1;
            } else {
                //flag = 1;
                printf("%d\n", mid);
                return 0;
            }
        }
    }
    return 0;
}

Resumir

       Lo anterior es de lo que quiero hablar hoy. Este artículo presenta la dicotomía y su aplicación en matrices desordenadas. En unos días, el editor escribirá algunos ejercicios sobre la dicotomía. Espero que puedas comentar después de leerlo. ¡Gracias!

Supongo que te gusta

Origin blog.csdn.net/2301_77868664/article/details/131977184
Recomendado
Clasificación