La entrevista debe: Diez algoritmos de clasificación clásicos (implementados en python, con análisis de complejidad y estabilidad)

Tabla de atributos de estabilidad y complejidad del algoritmo de clasificación de los diez principales

Inserte la descripción de la imagen aquí
Explicación del sustantivo de la imagen:

n: tamaño de los datos
k: el número de "cubos"
En el lugar: ocupa memoria constante, no ocupa memoria adicional
Fuera del lugar: ocupa memoria adicional

1. Clasificación de burbujas (clasificación de burbujas)

El principio del algoritmo de clasificación de burbujas es el siguiente:

a . Compare los elementos adyacentes. Si el primero es más grande que el segundo, intercambie los dos.
——
b) Haga el mismo trabajo para cada par de elementos adyacentes, desde el primer par al principio hasta el último par al final. En este punto, el último elemento debería ser el número más grande.
——
c . Repita los pasos anteriores para todos los elementos excepto el último.
——
d . Repita los pasos anteriores para cada vez menos elementos hasta que no haya un par de números para comparar

Complejidad y estabilidad: Complejidad
temporal: O (n ^ 2)
Complejidad espacial: O (1)
Estabilidad: Estable como un perro viejo, clasificación interna

Código de implementación de Python:

def bubble_sort(nums):
    n = len(nums)
    # 进行多次循环
    for c in range(n):
        for i in range(1, n - c):
            if nums[i - 1] > nums[i]:
                nums[i - 1], nums[i] = nums[i], nums[i - 1]
    return nums

2. Seleccione Ordenar

En cada pasada, se selecciona el elemento más pequeño (más grande) de los elementos de datos que se van a ordenar, y la secuencia se coloca en la parte superior de la secuencia numérica que se va a ordenar, hasta que se organizan todos los elementos de datos que se van a ordenar.

Ejemplo:
[4, 2, 3] Encuentra el más pequeño: 2, intercambia con el primer elemento
[2, 4, 3] Encuentra el más pequeño: 3, intercambia con el segundo elemento
[2, 3, 4]

Complejidad y estabilidad: Complejidad
temporal: O (n ^ 2)
Complejidad espacial: O (1)
Estabilidad: lista enlazada estable, matriz inestable, ordenación interna

Código de implementación de Python:

def select_sort(nums):
    n = len(nums)
    for i in range(n):
        for j in range(i, n):
            if nums[i] > nums[j]:
                nums[i], nums[j] = nums[j], nums[i]
    return nums

3. Orden de inserción (Orden de inserción)

Idea central: la ordenación por inserción es encontrar la posición de inserción en la matriz ordenada previamente

Complejidad y estabilidad: Complejidad
temporal: O (n ^ 2)
Complejidad espacial: O (1)
Estabilidad: Estable como un perro viejo, clasificación interna

Código de implementación de Python:

def insertion_sort(nums):
    n = len(nums)
    for i in range(1, n):
        while i > 0 and nums[i - 1] > nums[i]:
            nums[i - 1], nums[i] = nums[i], nums[i - 1]
            i -= 1
    return nums

4. Clasificación de colinas (clasificación de conchas)

Versión avanzada de ordenación por inserción. . .

Descripción del algoritmo:

Echemos un vistazo a los pasos básicos de la clasificación Hill. Aquí elegimos el incremento gap = length / 2, y el incremento de reducción continúa con gap = gap / 2. Esta selección incremental se puede representar mediante una secuencia, {n / 2, (n / 2) / 2 ... 1}, llamada secuencia incremental. La selección y prueba de la secuencia incremental de clasificación de Hill es un problema matemático. La secuencia incremental que elegimos se usa más comúnmente, y también es la incremental sugerida por Hill, llamada Hill incremental, pero de hecho, esta secuencia incremental no es la más excelente.

Primero divida la secuencia completa de registros que se clasificarán en varias subsecuencias para la clasificación por inserción directa, la descripción del algoritmo específico:

Paso 1: seleccione una secuencia de incremento t1, t2, ..., tk, donde Ti> TJ, TK = 1;
-
Paso 2: incrementa el número de secuencia k, k veces que se ordena la secuencia;
-
Paso 3: En cada clasificación pass, según el incremento ti correspondiente, la secuencia a ordenar se divide en varias subsecuencias de longitud m, y cada subtabla se inserta y ordena directamente. Solo cuando el factor de incremento es 1, toda la secuencia se trata como una tabla y la longitud de la tabla es la longitud de toda la secuencia.

Complejidad y estabilidad: Complejidad
temporal: O (nlogn)
Complejidad espacial: O (n)
Estabilidad: Muy estable, clasificación externa (se requiere espacio adicional)

Código de implementación de Python:

def shell_sort(nums):
    n = len(nums)
    gap = n // 2
    while gap:
        for i in range(gap, n):
            while i - gap >= 0 and nums[i - gap] > nums[i]:
                nums[i - gap], nums[i] = nums[i], nums[i - gap]
                i -= gap
        gap //= 2
    return nums

5. Fusionar clasificación (Fusionar clasificación)

La clasificación por fusión adopta el método de dividir y conquistar. Primero, la matriz se divide en subsecuencias para hacer las subsecuencias en orden, y luego las subsecuencias se ordenan y combinan en una matriz ordenada.

Descripción del algoritmo:

1. Divida la secuencia de entrada de longitud n en subsecuencias de longitud n / 2,
2. Utilice la clasificación por combinación en las dos subsecuencias,
3. Combine todas las subsecuencias.

Complejidad y estabilidad:
complejidad temporal: O (nlogn)
complejidad espacial: O (1)
estabilidad: inestable, tipo interno

Código de implementación de Python:

def merge_sort(nums):
    if len(nums) <= 1:
        return nums
    mid = len(nums) // 2
    # 分
    left = merge_sort(nums[:mid])
    right = merge_sort(nums[mid:])
    # 合并
    return merge(left, right)

def merge(left, right):
    res = []
    i = 0
    j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            res.append(left[i])
            i += 1
        else:
            res.append(right[j])
            j += 1
    res += left[i:]
    res += right[j:]
    return res

6. Clasificación rápida (clasificación rápida)

La clasificación rápida consiste en seleccionar un "centinela" (pivote), colocar menos que pivote a la izquierda y mayor que pivote a la derecha, dividir en dos partes, fijar la posición del pivote en la matriz y continuar ordenando el partes izquierda y derecha.

Quicksort utiliza dividir y conquistar para dividir una lista en dos sublistas. El algoritmo específico se describe a continuación:

Paso 1: seleccionar el número de columnas en un elemento, llamado "referencia" (Pivot);
-
Paso 2: reordenar las columnas, todos los elementos colocados delante de la referencia son pequeños que el valor de referencia, el valor de referencia es mayor que todos los elementos del swing Detrás del punto de referencia (el mismo número puede ir a cualquier lado). Una vez que la partición sale, el punto de referencia se encuentra en el medio de la secuencia. Esto se llama una operación de partición (Partición);
-
Paso 3: recursivamente (recursivo Esto) que el valor de referencia, el número de columnas y el subelemento es mayor que el número de columnas, un valor de referencia de clasificación del elemento.

Complejidad y estabilidad:
complejidad temporal: O (nlogn)
complejidad espacial: O (1)
estabilidad: inestable, tipo interno

Código de implementación de Python:

def quick_sort(nums):
    n = len(nums)

    def quick(left, right):
        if left >= right:
            return nums
        pivot = left
        i = left
        j = right
        while i < j:
            while i < j and nums[j] > nums[pivot]:
                j -= 1
            while i < j and nums[i] <= nums[pivot]:
                i += 1
            nums[i], nums[j] = nums[j], nums[i]
        nums[pivot], nums[j] = nums[j], nums[pivot]
        quick(left, j - 1)
        quick(j + 1, right)
        return nums

    return quick(0, n - 1)

7, clasificación de montón (clasificación de montón)

La clasificación de montón es un algoritmo de clasificación diseñado utilizando la estructura de datos del montón.

Descripción del algoritmo:

1. Construya una pila, ajuste la pila de abajo hacia arriba, de modo que el nodo padre tenga un valor mayor que el nodo hijo, formando una pila superior grande;
2. Cambie la parte superior de la pila y el último elemento, y reajuste el pila.

El método del montón de ajuste ha escrito recursividad e iteración, ¡que son muy fáciles de entender!

Complejidad y estabilidad:
complejidad temporal: O (nlogn)
complejidad espacial: O (1)
estabilidad: inestable, tipo interno

Código de implementación de Python:

def heap_sort(nums):
    # 调整堆
    # 迭代写法
    def adjust_heap(nums, startpos, endpos):
        newitem = nums[startpos]
        pos = startpos
        childpos = pos * 2 + 1
        while childpos < endpos:
            rightpos = childpos + 1
            if rightpos < endpos and nums[rightpos] >= nums[childpos]:
                childpos = rightpos
            if newitem < nums[childpos]:
                nums[pos] = nums[childpos]
                pos = childpos
                childpos = pos * 2 + 1
            else:
                break
        nums[pos] = newitem
    
    # 递归写法
    def adjust_heap(nums, startpos, endpos):
        pos = startpos
        chilidpos = pos * 2 + 1
        if chilidpos < endpos:
            rightpos = chilidpos + 1
            if rightpos < endpos and nums[rightpos] > nums[chilidpos]:
                chilidpos = rightpos
            if nums[chilidpos] > nums[pos]:
                nums[pos], nums[chilidpos] = nums[chilidpos], nums[pos]
                adjust_heap(nums, pos, endpos)

    n = len(nums)
    # 建堆
    for i in reversed(range(n // 2)):
        adjust_heap(nums, i, n)
    # 调整堆
    for i in range(n - 1, -1, -1):
        nums[0], nums[i] = nums[i], nums[0]
        adjust_heap(nums, 0, i)
    return nums

8. Contando Ordenar

La clasificación de conteo es un algoritmo típico de espacio por tiempo, que abre espacio de datos adicional para el almacenamiento y registra el valor de la matriz y el número de valores de la matriz con un número de índice.

Descripción del algoritmo:

1. Encuentre los valores máximos y mínimos de la matriz a ordenar,
2. Cuente el número de valores de la matriz,
3. Llene la matriz de destino al revés.

Complejidad y estabilidad: Complejidad
temporal: O (n + k)
Complejidad espacial: O (k), para arreglos con un gran rango de datos, se requiere mucho tiempo y memoria.
Estabilidad: Estable, clasificación externa

Código de implementación de Python:

def counting_sort(nums):
    if not nums: return []
    n = len(nums)
    _min = min(nums)
    _max = max(nums)
    tmp_arr = [0] * (_max - _min + 1)
    for num in nums:
        tmp_arr[num - _min] += 1
    j = 0
    for i in range(n):
        while tmp_arr[j] == 0:
            j += 1
        nums[i] = j + _min
        tmp_arr[j] -= 1
    return nums

9. Clasificación de cubos (clasificación de cubos)

La clasificación por depósitos es una versión mejorada de la clasificación por recuento. El principio es: los datos de entrada se distribuyen uniformemente, los datos se dividen en un número limitado de depósitos y cada depósito se clasifica por separado (es posible utilizar otros algoritmos o seguir usando recursivamente Clasificación de cubos, este artículo utiliza codificación recursiva)

Descripción del algoritmo:

1. El BucketSize de un bucket se establece artificialmente, ya que cuántos valores diferentes se colocan en cada bucket (es decir, BucketSize = 5, puede poner 5 números diferentes como [1, 2, 3,4,5] o 100,000 3, solo significa que el depósito puede almacenar varios valores diferentes);
——
2. Recorra los datos que se van a clasificar y coloque los datos uno por uno en el depósito correspondiente;
——
3. Ordene cada uno que no sea un depósito, puede use otros Método de clasificación, también clasificación recursiva;
——
4, no empalme de datos de cubeta vacía;

Complejidad y estabilidad: Complejidad
temporal: O (n ^ 2)
Complejidad espacial: O (n + k)
Estabilidad: estable, orden exterior

Código de implementación de Python:

def bucket_sort(nums, bucketSize):
    if len(nums) < 2:
        return nums
    _min = min(nums)
    _max = max(nums)
    # 需要桶个数
    bucketNum = (_max - _min) // bucketSize + 1
    buckets = [[] for _ in range(bucketNum)]
    for num in nums:
        # 放入相应的桶中
        buckets[(num - _min) // bucketSize].append(num)
    res = []

    for bucket in buckets:
        if not bucket: continue
        if bucketSize == 1:
            res.extend(bucket)
        else:
            # 当都装在一个桶里,说明桶容量大了
            if bucketNum == 1:
                bucketSize -= 1
            res.extend(bucket_sort(bucket, bucketSize))
    return res

10. Orden de Radix (Orden de Radix)

La clasificación de cardinalidad consiste en ordenar cada dígito del número, comenzando desde el dígito más bajo

Descripción del algoritmo:

1. Encuentre el valor máximo de la matriz y obtenga el número máximo de dígitos;
2. Tome cada bit del bit más bajo para formar una matriz de base;
3. Cuente y clasifique la base (contar y clasificar es adecuado para características de pequeña escala ).

Complejidad y estabilidad: Complejidad
temporal: O (n * k)
Complejidad espacial: O (n + k)
Estabilidad: estable, orden exterior

Código de implementación de Python:

def Radix_sort(nums):
    if not nums: return []
    _max = max(nums)
    # 最大位数
    maxDigit = len(str(_max))
    bucketList = [[] for _ in range(10)]
    # 从低位开始排序
    div, mod = 1, 10
    for i in range(maxDigit):
        for num in nums:
            bucketList[num % mod // div].append(num)
        div *= 10
        mod *= 10
        idx = 0
        for j in range(10):
            for item in bucketList[j]:
                nums[idx] = item
                idx += 1
            bucketList[j] = []
    return nums

Fuente de referencia: https://leetcode-cn.com/problems/sort-an-array/solution/python-shi-xian-de-shi-da-jing-dian-pai-xu-suan-fa/

Supongo que te gusta

Origin blog.csdn.net/weixin_44414948/article/details/114079540
Recomendado
Clasificación