Estructura de datos y fundamentos de algoritmos (Wang Zhuo) (33): clasificación por inserción binaria, clasificación por colinas

Tabla de contenido

Clasificación de inserción binaria

 Proyecto 1:

Problema: Faltan operaciones para mover elementos antes de insertarlos

Proyecto 2: (producto final, resultado)

clasificación de colinas

 Proyecto 1: (idea personal)

Respuesta estándar: (respuesta PPT)

Explicación: (La secuencia lógica del algoritmo cuando el programa se ejecuta realmente es diferente de lo que enseñó el Sr. Wang Zhuo en la clase en línea)

(1): etapa de asignación

(2): La comparación de la primera ronda [primera vez]

 (3): Comparación de la segunda ronda con la (d) ronda [primera vez]

(4): Comparación de la primera ronda con la (d) ronda [la segunda ronda y las subsiguientes]

Aquí viene el punto:

En cuanto a cómo ajustar los diferentes tamaños de intervalo d cuando se comparan sucesivamente, el método dado en la respuesta estándar aquí es:

La respuesta benevolente:

localización


Clasificación de inserción binaria


Escriba el siguiente programa directamente basado en el ejemplo real y el boceto: 

 Proyecto 1:

void BinsertSort(SqList& L)
{
    int i ,low = 1, high = i - 1;
    for (i = 1; i < L.length; i++)
    {
        if (L.r[i].key < L.r[i - 1].key)
            L.r[0] = L.r[i];
        //if可以放到最高优先级
        for (int mid = (low + high) / 2; high > low; mid = (low + high) / 2)
        {
            if (L.r[0].key < L.r[mid].key)
                high = mid - 1;
            else //if (L.r[0].key > L.r[mid].key)
                low = mid + 1;
        }
        L.r[high + 1].key = L.r[0].key;
        //L.r[low - 1].key = L.r[0].key;
    }
}

inserto binario;
binario: binario; basado en solo dos números; binario; que consta de dos partes;

Problema: Faltan operaciones para mover elementos antes de insertarlos


Proyecto 2: (producto final, resultado)

void BinsertSort(SqList& L)
//binary insert;
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    int i;
    for (i = 1; i < L.length; i++)
        //i表示位序
    {
        if (L.r[i].key < L.r[i - 1].key)
            L.r[0] = L.r[i];
int low = 1, high = i - 1;
        for (int mid = (low + high) / 2; high > low; mid = (low + high) / 2)
        {
            if (L.r[0].key < L.r[mid].key)
                high = mid - 1;
            else //if (L.r[0].key > L.r[mid].key)
                low = mid + 1;
        }
        for (int j = i; j >= high + 1; j--)
            L.r[j + 1].key = L.r[j].key;

        L.r[high + 1].key = L.r[0].key;
        //L.r[low - 1].key = L.r[0].key;
    }
}

clasificación de colinas

Escriba el siguiente programa directamente basado en el ejemplo real y el boceto: 

 Proyecto 1: (idea personal)

void ShellSort(SqList& L) 
{
    for (int i = 0; i <= L.length / 5; i++)
    {
        for (int i = 0; i <= L.length; i += 5)
        {
            每次都把数据存储到中序二叉树,再用中序遍历把这些元素全部都重新插回去
        }
        递归...
    }
}

Respuesta estándar: (respuesta PPT)

void ShellInsert(SqList& L, int d)
//distance:每次一步往后跨多远(5,3,1...)
{
    int i, j;
    for (i = d + 1; i < L.length; i++) 
    {
        if (L.r[i].key < L.r[i - d].key) 
            //比较的诸多元素里,第二个元素大于第一个元素
        {
            L.r[0] = L.r[i];  
            for (j = i - d; //第一个元素
                j > 0 && (L.r[0].key < L.r[j].key);
                j -= d)
                L.r[j + d] = L.r[j];  //记录后移
            L.r[j + d] = L.r[0];  
        }
    }
}
void ShellSort(SqList& L, int dlta[], int t)
//t:循环总共趟数
{
    for (int k = 0; k < t; k++)
        ShellInsert(L, dlta[k]); 
    //dlta[k]:增量(5, 3, 1...)
}

Explicación: (La secuencia lógica del algoritmo cuando el programa se ejecuta realmente es diferente de lo que enseñó el Sr. Wang Zhuo en la clase en línea)


(1): etapa de asignación

El valor inicial de i es el segundo elemento de cada comparación.

Entre los muchos elementos comparados, si el segundo elemento es mayor que el primer elemento: inicie el bucle


(2): La comparación de la primera ronda [primera vez]

La primera operación de la primera ronda de comparación solo compara los dos elementos previamente seleccionados:


Compara los elementos 1 y (d+1)

  1. Pon el segundo elemento en el centinela.
  2. El primer elemento cubre al segundo elemento.
  3. Luego transfiera el segundo elemento del centinela a la posición del primer elemento.

Entonces: j-=d; => j<0


La primera ronda de comparación ha terminado.

De hecho, la clasificación completa de este bloque no ha terminado.

Sin embargo, debido al hecho de que la clasificación Hill se desvía de las ideas algorítmicas enseñadas por el profesor

Por lo tanto, para: dividimos los datos en d partes y realizamos un total de d rondas de clasificación en la primera ronda del algoritmo, se detiene y termina aquí


Entonces ( después de la primera ronda de comparación ), la operación que realizamos no fue como dijo el Sr. Wang:

Vaya al siguiente bloque para filtrar, el tercero y los demás elementos subsiguientes para comparar y ordenar

En su lugar, suspenda temporalmente la operación del algoritmo de bloque y encuentre el segundo elemento que almacenamos dentro de los datos:


 (3): Comparación de la segunda ronda con la (d) ronda [primera vez]

Comparar:

El 2º y (d+2)º, el 3º y (d+3)º, el 4º y (d+4)º...

Hasta la comparación con la (d)ésima ronda: désima y (d*2)ésima

Ahora, ya tenemos la primera secuencia 2d de elementos ordenados:

Los primeros d elementos (k: orden de bits)

respectivamente menor que

El siguiente elemento de bit (d+k)


(4): Comparación de la primera ronda con la (d) ronda [la segunda ronda y las subsiguientes]

Similar a los pasos de comparación (2) y (3), continúe comparando hasta que se comparen todos los elementos subsiguientes:

 Sin embargo, dentro de este lugar (paso 4):

Después de cada comparación [distinguido por las reglas de secuencia que definimos (cada d como grupo)]

Después de los dos últimos elementos dentro

También realizamos una operación más allá de (2), (3) pasos:

Vuelva a recorrer todos los elementos delante de la secuencia de cada grupo

Es decir:

Después de comparar los dos últimos elementos de cada secuencia de cola, continúe comparando uno por uno hacia adelante

Si/siempre que el elemento posterior sea más pequeño que el elemento anterior en la comparación, coloque el último elemento al frente


Aquí viene el punto:

Después de comparar un total de más de dos rangos de datos, en cada ronda de cada comparación: cada vez

Continúe comparando [el elemento más pequeño después de la comparación] con [el elemento en la secuencia anterior]

A partir del elemento señalado por i, compare todos los elementos delante de la secuencia completa


En este proceso, hemos completado todo/todo el proceso (proceso) de la operación de "clasificación":

comparar uno por uno

Cambie el elemento pequeño a la posición frontal (mueva el elemento pequeño al frente)

El elemento grande se cambia a la posición trasera (mover hacia atrás cuando encuentre uno grande)

 Y después de comparar más de dos rangos de datos, cada vez que se comparan los elementos

La operación de comparar todos los elementos anteriores (recorridos) es muy sencilla, añade una frase en el ciclo de cada comparación del programa:

Siga comparando con el elemento anterior hasta que se hayan comparado todos los elementos anteriores de esta secuencia

Esto esta hecho:

            for (j = i - d; //第一个元素
                j > 0 && (L.r[0].key < L.r[j].key);
                j -= d)

El código de diseño de sentencia for ejecutado por este programa

Es el núcleo y la sutileza de  la construcción del marco de todo el proceso de operación del programa de algoritmo.


En cuanto a cómo ajustar los diferentes tamaños de intervalo d cuando se comparan sucesivamente, el método dado en la respuesta estándar aquí es:

Cada vez a través de una determinada regla dlta[]

(¿Función? ¿O qué? No dio la relación correspondiente cada vez aquí, y no sé qué está haciendo) para hacer algunos cambios regulares:

    for (int k = 0; k < t; k++)//t:循环总共趟数
        ShellInsert(L, dlta[k]); 

Estoy un poco confundido por él aquí, y no sé qué está tramando.


Como siento que el método de control que escribió es un montón de mierda, echemos un vistazo a este ejemplo de una operación que divide todos los datos en dos cada vez:

La respuesta benevolente:

//希尔排序
void ShellSort(int A[], int n)
{
    int d, i, j;
    //A[0]只是暂存单元,不是哨兵,当j<=0时,插入位置已到
    for (d = n / 2; d >= 1; d = d / 2)
        //步长变化
        for (i = d + 1; i <= n; ++i)
            if (A[i] < A[i - d])
                //需将A[i]插入有序增量子表
            {
                A[0] = A[i];
                //暂存在A[0]
                for (j = i - d; j > 0 && A[0] < A[j]; j -= d)
                    A[j + d] = A[j];
                //记录后移,查找插入的位置
                A[j + d] = A[0];
            }//if
}

De acuerdo con las condiciones previas que configuramos, modifique según sea necesario: (localice el programa)

localización:

void ShellSort(SqList& L)
{
    int  i, j;
    for (int d = L.length / 2; d >= 1; d = d / 2)
        //步长变化

        for (i = d + 1; i <= L.length; ++i)
            if (L.r[i].key < L.r[i - d].key)
            {
                L.r[0] = L.r[i];
                for (j = i - d; j > 0 && L.r[0].key < L.r[j].key; j -= d)
                    L.r[j + d] = L.r[j];
                L.r[j + d] = L.r[0];
            }//if
}

Desde este punto de vista, de hecho (en realidad), el programa utilizado para controlar la compensación d de cada comparación continua solo necesita un párrafo:

    for (int d = L.length / 2; d >= 1; d = d / 2)

Supongo que te gusta

Origin blog.csdn.net/Zz_zzzzzzz__/article/details/130310206
Recomendado
Clasificación