Estructura de datos y algoritmo (implementación de Golang) (20) Clasificación de algoritmos de selección

Seleccionar orden

La ordenación por selección, en general, nos referimos a la ordenación por selección simple, también llamada ordenación por selección directa. No intercambia elementos adyacentes como la ordenación por burbujas. En su lugar, selecciona el elemento más pequeño y solo necesita intercambiarlo una vez por iteración. Aunque el número de intercambios es mucho menor que el burbujeo, la eficiencia es tan mala como la clasificación por burbujeo.

La selección de selección es un algoritmo de selección de selección.

Cuando juego al póker, habitualmente escaneo de izquierda a derecha, luego coloco la carta más pequeña en el extremo izquierdo, y luego continúo escaneando la segunda carta más pequeña de izquierda a derecha desde la segunda carta y la coloco en la más pequeña En el lado derecho de la tarjeta, repita esto. El tipo de selección es particularmente similar al tipo cuando juego al póker.

1. Introducción al algoritmo

Hay un montón de secuencia de números aleatorios, tales como: 5 9 1 6 8 14 6 49 25 4 6 3.

La primera iteración, comenzando desde el primer número, escanea de izquierda a derecha, encuentra el número 1 más pequeño y cambia la posición con el primer número en la secuencia.

La segunda iteración, comenzando desde el segundo número, escanea de izquierda a derecha, encuentra el segundo número más pequeño 3 e intercambia posición con el segundo número en la secuencia.

La tercera ronda de iteración, comenzando desde el tercer número, escanea de izquierda a derecha, encuentra el tercer número más pequeño 4 e intercambia posición con el tercer número en la secuencia.

La enésima iteración: ...

Después del intercambio, el resultado final es : 1 3 4 5 6 6 6 8 9 14 25 49, podemos ver que se ha ordenado.

Cada vez que escanea la secuencia para encontrar el número más pequeño, y luego intercambia con el primer número, y luego excluye el primer número, repite esta operación desde el segundo número, esta clasificación se llama clasificación de selección simple.

Para un ejemplo simple, elija ordenar una secuencia de 4 elementos 4 2 9 1:

[]表示排好序

起始: 4 2 9 1  未排序数列从左扫描最小的数是 1,与第一个元素 4 交换,交换 1,4
一轮: [1] 2 9 4 未排序数列从左扫描最小的数是 2,不需要交换
二轮: [1 2] 9 4 未排序数列从左扫描最小的数是 4,与第三个元素 9 交换,交换 4,9
三轮: [1 2 4] 9 未排序数列只有 1 个数,结束
结果: [1 2 4 9]

Hay tantas comparaciones como tipos de burbujas, porque el proceso de escaneo también es un proceso de comparación, pero el número de intercambios se reduce a 1 por ronda. peores restos vez mejores y complejidad: O(n^2).

La ordenación por selección es un algoritmo de ordenación inestable, como una matriz: el [5 6 5 1]número más pequeño en la primera iteración es 1, luego 5intercambia la posición con el primer elemento , de modo que el número 1y la posición de 5intercambio de números , resultando en dos números idénticos 5después de la ordenación La ubicación ha cambiado.

2. Implementación de algoritmos

package main

import "fmt"

func SelectSort(list []int) {
    n := len(list)
    // 进行 N-1 轮迭代
    for i := 0; i < n-1; i++ {
        // 每次从第 i 位开始,找到最小的元素
        min := list[i] // 最小数
        minIndex := i  // 最小数的下标
        for j := i + 1; j < n; j++ {
            if list[j] < min {
                // 如果找到的数比上次的还小,那么最小的数变为它
                min = list[j]
                minIndex = j
            }
        }

        // 这一轮找到的最小数的下标不等于最开始的下标,交换元素
        if i != minIndex {
            list[i], list[minIndex] = list[minIndex], list[i]
        }
    }
}

func main() {
    list := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3}
    SelectSort(list)
    fmt.Println(list)
}

En cada iteración, mantendremos el número mínimo de esta ronda: miny el subíndice del número mínimo :, y minIndexluego iniciaremos el escaneo, si el número de escaneos es menor que el número, luego reemplace los subíndices mínimos y mínimos, después del escaneo determinar si el cambio debe entonces intercambiar: list[i], list[minIndex] = list[minIndex], list[i].

Tres, mejora del algoritmo

El algoritmo anterior necesita comenzar desde un cierto número y escanear hasta el final. Podemos optimizar el algoritmo para reducir la complejidad a la mitad.

En cada ronda, además de encontrar el número mínimo, también encontramos el número máximo, y luego intercambiamos con los elementos frontal y posterior por separado, de modo que el número de ciclos se reduce a la mitad, como por ejemplo:

package main

import "fmt"

func SelectGoodSort(list []int) {
    n := len(list)

    // 只需循环一半
    for i := 0; i < n/2; i++ {
        minIndex := i // 最小值下标
        maxIndex := i // 最大值下标

        // 在这一轮迭代中要找到最大值和最小值的下标
        for j := i + 1; j < n-i; j++ {
            // 找到最大值下标
            if list[j] > list[maxIndex] {
                maxIndex = j // 这一轮这个是大的,直接 continue
                continue
            }
            // 找到最小值下标
            if list[j] < list[minIndex] {
                minIndex = j
            }
        }

        if maxIndex == i && minIndex != n-i-1 {
            // 如果最大值是开头的元素,而最小值不是最尾的元素
            // 先将最大值和最尾的元素交换
            list[n-i-1], list[maxIndex] = list[maxIndex], list[n-i-1]
            // 然后最小的元素放在最开头
            list[i], list[minIndex] = list[minIndex], list[i]
        } else if maxIndex == i && minIndex == n-i-1 {
            // 如果最大值在开头,最小值在结尾,直接交换
            list[minIndex], list[maxIndex] = list[maxIndex], list[minIndex]
        } else {
            // 否则先将最小值放在开头,再将最大值放在结尾
            list[i], list[minIndex] = list[minIndex], list[i]
            list[n-i-1], list[maxIndex] = list[maxIndex], list[n-i-1]
        }
    }
}

func main() {
    list := []int{5}
    SelectGoodSort(list)
    fmt.Println(list)

    list1 := []int{5, 9}
    SelectGoodSort(list1)
    fmt.Println(list1)

    list2 := []int{5, 9, 1}
    SelectGoodSort(list2)
    fmt.Println(list2)

    list3 := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3}
    SelectGoodSort(list3)
    fmt.Println(list3)

    list4 := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6}
    SelectGoodSort(list4)
    fmt.Println(list4)
}

Salida:

[5]
[5 9]
[1 5 9]
[1 3 4 5 6 6 6 8 9 14 25 49]
[1 4 5 6 6 6 8 9 14 25 49]

La ordenación optimizada sigue siendo muy lenta, es fácil de entender, pero no se recomienda para ingeniería.

Entrada de artículo de serie

Soy la estrella Chen, bienvenido he escrito personalmente estructuras de datos y algoritmos (Golang lograr) , comenzando en el artículo para leer más amigable GitBook .

Supongo que te gusta

Origin www.cnblogs.com/nima/p/12724853.html
Recomendado
Clasificación