Clásicos algoritmos de ordenación - con código Python

Enlaces de referencia:

https://www.cnblogs.com/fivestudy/p/10212306.html

https://blog.csdn.net/qq_43549984/article/details/89426394#Bubble_Sort_21

1. ¿Qué algoritmo de ordenación?

Algoritmo de ordenación es uno de los algoritmos, "Estructuras de Datos y Algoritmos" en el más básico.

algoritmo de ordenación se puede dividir en clasificación interna y la clasificación externa .

  • clasificación interna ordena los registros de datos en la memoria.
  • la clasificación externa debido a una gran clase de datos, no se puede dar cabida a todo tipo de registro, en el proceso de clasificación requiere el acceso a la memoria externa.

Comunes algoritmos internos de clasificación : burbuja, inserción, fusión, seleccione la fila, rápido, Colina, pila de clasificación, Radix sort y así sucesivamente.

Clasificación de complejidad del algoritmo

algoritmo Tiempo Complejidad Complejidad de tiempo complejidad complejidad espacio espacio
Mejor Promedio Peor Peor estabilidad
fila rápida QuickSort O (n log (n)) O (n log (n)) O (n ^ 2) O (n log (n)) inestable
fusión mergesort O (n log (n)) O (n log (n)) O (n log (n)) O (n) estable
burbujeante BubbleSort O (n) O (n ^ 2) O (n ^ 2) O (1) estable
inserción InsertionSort O (n) O (n ^ 2) O (n ^ 2) O (1) estable
la selección SelectionSort O (n ^ 2) O (n ^ 2) O (n ^ 2) O (1) inestable

2. Tiempo complejidad

Orden de la plaza O (n ^ 2) Insertar seleccionar burbuja
Linealidad de la orden O (n log (n)) fila rápida fusión heapsort
orden lineal O (n) Radix sort cubo especie Ordenar cuadro

3. Estabilidad

estable burbuja Insertar fusión número cardinal
inestable seleccionar fila rápida colina heapsort

4. El ordenamiento de burbuja

Burbuja Ordenar algoritmo de clasificación es un simple, que en repetidas ocasiones a través de la lista, la comparación de los dos elementos vecinos, si el orden equivocado, la conmutación de los mismos. El algoritmo es relativamente una especie, que es una pequeña o grandes elementos "burbuja" a la parte superior de la lista se nombran. A pesar de que el algoritmo es muy simple, pero para la mayoría de los problemas, es demasiado lento.

4.1 análisis sintáctico etapas de algoritmo

  • Comparación de elementos adyacentes. Si el primero es mayor que el segundo, los dos de ellos intercambiaron.
  • Hacer el mismo trabajo para cada par de elementos adyacentes, desde el principio del primer par hasta el final de la última pareja. Una vez hecho esto, el último elemento es el número más grande.
  • Repita estos pasos para todos los elementos, además de los ya ordenados.
  • Continúa repetir los pasos anteriores para cada vez menos y menos elementos, un par de números hasta que no hay necesidad de comparar.

4.2 gráfico

burbuja
burbuja

4.3 Código

"""
def bubble_sort(alist):
    # 方式1
    for i in range(len(alist)-1):
        for j in range(len(alist)-1-i):
            if alist[j] > alist[j+1]:
                alist[j], alist[j+1] = alist[j+1], alist[j]
    return alist
"""

def bubble_sort(alist):
    # 方式2
    for i in range(len(alist)-1):
        flag = True
        for j in range(len(alist)-1-i):
            if alist[j] > alist[j + 1]:
                alist[j], alist[j + 1] = alist[j + 1], alist[j]
                flag = False
        if flag is True:
            break
    return alist


def test_bubble_sort():
    import random
    alist = list(range(10))
    random.shuffle(alist)
    result = bubble_sort(alist)
    print(result)

test_bubble_sort()

4.4 Analizada

En primer lugar, la forma 1

  1. n-1 ciclos de
  2. En cada ronda del bucle, independientemente de si el tamaño de los elementos adyacentes se han ordenado. Será la comparación de tamaño.
  3. Recursivamente determinar de forma continua, después de consulta n-1 de la rueda para obtener un resultado final.

En segundo lugar, la forma 2

  1. n-1 rueda de consultas
  2. Cada consulta ronda, antes de los elementos para determinar el tamaño de la bandera soporte adyacente: se refiere a la necesidad de sustituir el valor predeterminado. Después de introducir cada bucle si la condición adyacente al elemento frontal es mayor que la parte posterior, por lo que el intercambio de datos, y cambiar la bandera es falsa, hasta el final de la actual ronda de circulación.
  3. siguiente ciclo comienza, bandera de inicialización, cuando la actual ronda de circulación si todos los elementos adyacentes cumple la orden (ascendente o descendente), se redondear fuera de circulación.
  4. Cuando (cuando ascendente o descendente) parámetros iniciales por defecto, el n-ésimo de la rueda a través del bucle exterior, el bucle interior se ejecuta sólo veces CORTE1, a continuación, fuera del bucle, la complejidad de tiempo óptimo es O (n) . El peor de los casos, se ejecuta el bucle interno n veces también requiere, peor complejidad de tiempo caso es O (n ^ 2) .

5. Selección Ordenar

Selección Ordenar algoritmo de clasificación es una comparación in situ, la complejidad de tiempo de O (n ^ 2), por lo que es relativamente baja eficiencia en una lista grande.
Sin embargo, el algoritmo es conocido por su simplicidad, y en algunos casos, tiene ventajas de rendimiento sobre algoritmos más complejos, especialmente cuando la memoria auxiliar tiempo limitado.

lista de entrada de selección Ordenar divide en dos partes: ordenados sublistas (el extremo frontal de la lista), y el sub-lista para ser ordenados. Inicialmente, la sub-lista ordenada está vacía, sub-lista desordenada es la lista completa. Algoritmo examinado la lista para ser ordenados sub-elemento más pequeño, que ha de ser intercambiado con el ordenamiento elemento más a la izquierda, y ordenó sub-lista para el borde derecho de un elemento para continuar.

5.1 análisis sintáctico etapas de algoritmo

  • En primer lugar, encontrar la secuencia más pequeño de elementos no seleccionados (grande), la posición de inicio se almacena en la secuencia ordenada
  • De los restantes sin clasificar, a continuación, seguir buscando el elemento mínimo elemento (grande), y luego en el final de la secuencia ordenada.
  • El segundo paso se repite hasta que se ordenan completaron todos los elementos.

5.2 gráfico

selección Ordenar
Aquí Insertar imagen Descripción

5.3 Código

def select_sort(alist):
    for i in range(len(alist)):
        min_num = i
        for j in range(i+1, len(alist)):
            if alist[j] < alist[min_num]:
                min_num = j
        alist[i], alist[min_num] = alist[min_num], alist[i]
    return alist

5.4 Analizada

  1. lazo mínima se encuentra lista no ordenada (lista ya ordenados, y el último valor de comparación de tamaño), y el último valor de la lista ordenada de cambio.
  2. La lista inicial de encontrar un primer valor mínimo, ajuste el valor inicial por defecto, es necesario bucle externo len (a-lista)
  3. La configuración predeterminada maneja como el valor mínimo de la variable i de bucle externo
  4. Seleccione el bucle mínimo interior (el valor inicial y el comparativo mínimo) elementos, el valor mínimo se actualiza si encontrado subíndice, el bucle hasta el final del valor inicial y el valor mínimo del intercambio; ronda hasta el final del bucle si no se encuentra, iniciar la siguiente ronda fuera del bucle.

6. ordenación por inserción

Inserción Ordenar es un simple algoritmo de clasificación requiere sólo un pase a través de la matriz para generar la clasificación final. Su eficacia es menor que una larga lista de algoritmos más avanzados, sin embargo, tiene las siguientes ventajas:
una, simple, unas pocas líneas de código para completar.
En segundo lugar, el pequeño conjunto de datos es muy eficaz (relativamente).
Tres, (^ 2 n) algoritmo es más eficiente que otros sencilla O en la práctica.
En cuarto lugar, la adaptación, cuando la entrada de cada elemento de su posición final no es más de k, la complejidad de tiempo de tan sólo O (kn).
Cinco estable, no cambia el orden relativo de los elementos que tienen valores iguales.
En sexto lugar, la complejidad espacial baja, sólo O (1).
Siete algoritmo de línea puede ordenar mientras se leen, no necesita leer toda la matriz.

6,1-análisis etapas de algoritmo

  • El primer elemento a ser considerado como una secuencia de primera ordenada de una secuencia ordenada, el segundo elemento es el último elemento como secuencia sin clasificar.
  • secuencia Unsorted de principio a fin escanea secuencialmente, el elemento de exploración se inserta en una posición adecuada de cada secuencia ordenada. (Si los elementos para ser insertados en una secuencia ordenada de elementos son iguales, los elementos a ser insertados se insertan en la parte posterior del elemento de iguales.)

6.2 gráfico

Insertar
Aquí Insertar imagen Descripción

6.3 Código

def insert_sort(alist):
    for i in range(1, len(alist)):
        for j in range(i, 0, -1):
            if alist[j] < alist[j-1]:
                alist[j], alist[j-1] = alist[j-1], alist[j]
            else:
                break
    return alist

6.4 Analizada

análisis Resumen:

O cuando jugamos, y cómo las tarjetas de clasificación más rápido?

  1. Nuestra primera tarjeta con el valor inicial
  2. determinación primer ciclo, determina si la segunda de la primera tarjeta de Da, entonces la secuencia de interruptor es no, no hay una posición fija, de bucle ronda.
  3. La segunda ronda del ciclo, la tercera tarjeta se determina después de la reina que el segundo, ubicación, entonces la secuencia de interruptor está no, no hay fijo; en comparación con la primera tarjeta, si la tarjeta 1 no es grande, la secuencia continúa el intercambio, hay la posición no se mueve. Fuera de la actual ronda de circulación.
  4. Por lo tanto, después de la n rueda 1-ciclo para obtener un resultado final.

Complejidad de tiempo:

mejor en)

peor: O (n ^ 2)

La clave está en el código else, break. Cuando la lista está en orden ascendente o descendente tiene, y no satisfacer la condición de la comparación de dos tamaño del elemento de cambio, lo que indica que el elemento de mayor o menor que el elemento anterior, ya que el elemento frontal más grande que todos los elementos que tiene o pequeños, todos ellos pueden salir de este ciclo. Después de n ciclos de equivalente, sólo se realiza una vez cada salto de ciclo, por lo que la complejidad de tiempo óptimo es O (n).

7. fusión especie

Combinar tipo es un eficiente, versátil, relativamente algoritmo de clasificación basado en el algoritmo utiliza la idea de la partición, la cuestión más amplia de la clase atribuida a resolver en una escala más pequeña.

Combinar ordenar los siguientes pasos:

En primer lugar, la lista no ordenada en dos elementos en el mismo número de sub-series.

En segundo lugar, pedir dos sub-series, y luego fusionarlas.

7.1 definiciones

Combinar tipo es el algoritmo divide y vencerás, los primeros puntos, (composición comparativa antes de la orden descendente) en combinación. Los dos pasos principales.

  1. Dividiendo lista no seleccionados continuo hasta que hay N sublistas, cada sublista tiene un elemento "sin clasificar", N es el número de elementos de la matriz original.
  2. El combinado repiten, es decir, una vez que los dos sub-listas se combinan para generar un nuevo sub-lista ordenada hasta que esté completamente incorporado en todos los elementos en una matriz ordenada.

7.2 gráfico

fusión
Aquí Insertar imagen Descripción

7.3 aplicación de código

# coding:utf-8
def merge_sort(alist):
    num = len(alist)
    if num == 1:
        return alist

    mid = num // 2
    left_li = merge_sort(alist[:mid])
    right_li = merge_sort(alist[mid:])

    left_pointer, right_pointer = 0, 0
    result = []

    while left_pointer < len(left_li) and right_pointer < len(right_li):
        if left_li[left_pointer] < right_li[right_pointer]:
            result.append(left_li[left_pointer])
            left_pointer += 1
        else:
            result.append(right_li[right_pointer])
            right_pointer += 1
    result += left_li[left_pointer:]
    result += right_li[right_pointer:]
    return result


result2 = merge_sort([1, 8, 7, 3, 5, 6, 4, 2, 9])
print(result2)

7.4 Analizada

  1. Dividir: hasta que el resultado independiente de división individual, cuando una longitud individual 1, a fusionar.
  2. El resultado de la variable global para aceptar la fusión
  3. El puntero izquierdo y el establecimiento de un valor inicial de 0 puntero derecho
  4. El análisis de la longitud del ciclo de ajuste (y de la condición) sobre la lista de punteros después de las condiciones debe ser menor que aproximadamente dividida. (Prevención de valor de lista puntero excede el intervalo de índice), cuando la condición no se cumple fuera del bucle.
  5. Combinar: El valor del puntero de aproximadamente el tamaño de la comparación lista. Pequeño almacena en primer lugar las variables globales dentro del resultado combinado, y el correspondiente puntero de lista + 1 = Dividir
  6. Cuando el valor de una lista de todos dividida la memoria fusionó resultado, el valor del puntero de lista de fractura alcanza el valor máximo índice. Otra lista de división, sobre todo cuando gran tamaño en etapas de comparación que 5 valor del resultado combinado se ha almacenado, y la lista se ordena dividida estado, puede ser directamente sobre la base de los resultados se han combinado, junto con la demolición puntos lista puntero al último valor de todos los elementos. (Nota: cuando se alcanza un valor de puntero de una lista de la resolución máxima, el valor del puntero toma el resultado final es una lista vacía, por ejemplo, a = [0,1,2,3], y una [4:] valores son nulos lista)
  7. Volver a los resultados

Complejidad de tiempo:

mejor: O (n log (n))

peor: O (n log (n))

7.5 código que se ejecuta pasos

def merge_sort([1, 8, 7, 3, 5, 6, 4, 2]):
    mid = 4
    left_li = def merge_sort([1, 8, 7, 3]):
        mid = 2
        left_li = def merge_sort([1, 8]):
            mid = 1
            left_li = def merge_sort([1]):
                return alist  # 到这里第7含的merge函数执行完毕(得到结果left_li=[1]),第7行的函数知识第5含函数的一含代码,继续向下执行.
            right_li = def merge_sort([8]): 
                return alist  # 同第8行代码一样,第9含的函数也是第5含代码函数的一行代码,得到结果right_li=[8]),继续向下执行.
            # 左右指针=0
            # result = []
            # 循环判断
                result= [1], 左指针 = 1, 右指针 = 0
            result = [1] + [] = [1]
            result = [1] + [8] = [1,8]
            return result # 到这里第5行代码执行完毕,得到结果left_li = [1, 8]
        right_li = def merge_sort([7, 3]):
            mid = 1
            left_li = [7]
            right_li = [3]
            # 左右指针=0
            # result = []
            # 循环判断
                result= [3], 右指针 = 1, 左指针 = 0
            result = [3] + [] = [3]
            result = [3] + [7] = [3,7]
            return result # 到这里第18行代码执行完毕,得到结果right_li = [3, 7]
        left_li = [1, 8]
        right_li = [3, 7]
        # 左右指针=0
        # result = []
        # 循环判断
        result= [1], 左指针 = 1, 右指针 = 0
        result= [1,3], 右指针 = 1, 左指针 = 1
        result= [1,3,7], 右指针 = 2, 左指针 = 1
        result = [1,3,7] + [8] = [1,3,7,8]
        result = [1,3,7,8] + [] = [1,3,7,8]
        return result # 到这里第3行代码执行完毕,得到结果left_li = [1,3,7,8]
    right_li = def merge_sort([5,6,4,2]):
        # 执行步骤同第4行到第39行代码一样.
         return result # 到这里第40行代码执行完毕,得到结果right_li = [2,4,5,6]
    left_li = [1,3,7,8]
    right_li = [2,4,5,6]
    # 左右指针=0
    # result = []
    # 循环判断
    result= [1], 左指针 = 1, 右指针 = 0
    result= [1,2], 右指针 = 1, 左指针 = 1
    result= [1,2,3], 左指针 = 2, 右指针 = 1
    result= [1,2,3,4], 左指针 = 2, 右指针 = 2
    result= [1,2,3,4,5], 右指针 = 3, 左指针 = 2
    result= [1,2,3,4,5,6], 右指针 = 4, 左指针 = 2
    # 到这里右指针 = 4, 左指针 = 2, 不满足循环条件,
    result = [1,2,3,4,5,6] + [7,8] = [1,2,3,4,5,6,7,8]
    result = [1,2,3,4,5,6,7,8] + [] = [1,2,3,4,5,6,7,8]
    return result # 到这里第1行代码执行完毕,得到结果result = [1,2,3,4,5,6,7,8]

8. Ordenación rápida

8.1 definiciones

Rápida especie es también un divide y vencerás algoritmos tales como ordenamiento por mezcla. Aunque es un poco complicado, pero en la mayoría implementación estándar, que se realiza más rápido que el ordenamiento por mezcla, y rara vez se logra la complejidad del peor caso de O (n). Tiene tres pasos principales:

  1. Seleccionar un elemento de la matriz, se hace referencia a pivote.
  2. Ordenar la matriz, de modo que todos los elementos se encuentran antes de que el pivote es menor que el pivote, y el pivote es mayor que todos los valores para los elementos están posicionados de pivote (valores iguales se pueden mover en cualquier dirección). Este paso se denomina a menudo partición.
  3. El procedimiento anterior se aplica de forma recursiva submatrices antes y después del pivote.
    La situación básica es array recursiva de tamaño 0 o 1, que están dispuestos, por definición, no hay necesidad de ordenarlos.

8.2 gráfico

fila rápida
fila Fast 2

8.3 aplicación de código

Modo 1:

def quick_sort(alist):
    if len(alist) < 2:  # 递归出口,当数组是空数组或者只有一个元素的数组都是有序的。
        return alist
    else:
        pivot_index = 0
        pivot = alist[pivot_index]
        less_part = [i for i in alist[pivot_index+1:] if i <= pivot]
        great_part = [i for i in alist[pivot_index+1:] if i > pivot]
        return quick_sort(less_part) + [pivot] + quick_sort(great_part)

Modo 2:

def quick_sort(li, start, end):
    if start >= end:
        return

    l_pointer = start
    r_pointer = end
    pivot = li[l_pointer]

    while l_pointer < r_pointer:
        while l_pointer < r_pointer and li[r_pointer] >= pivot:
            r_pointer -= 1
        li[l_pointer], li[r_pointer] = li[r_pointer],  li[l_pointer]

        while l_pointer < r_pointer and li[l_pointer] < pivot:
            l_pointer += 1
        li[l_pointer], li[r_pointer] = li[r_pointer],  li[l_pointer]

    li[l_pointer] = pivot

    quick_sort(li, start, l_pointer - 1)
    quick_sort(li, l_pointer + 1, end)

Supongo que te gusta

Origin www.cnblogs.com/yblackd/p/12470766.html
Recomendado
Clasificación