Revisión de las estructuras de datos y algoritmos (a) algoritmo de ordenación (I)

En este artículo se introducirá el algoritmo más común de clasificación (utilizando el lenguaje JavaScript)

PD: Aquí voy a tratar de usar el lenguaje de sintaxis independiente para escribir, no hay que preocuparse demasiado acerca de la lengua, es importante darse cuenta de la idea del algoritmo

1, ordenamiento de burbuja

La matriz se divide en regiones ordenados (izquierda) y desordenada región (a la derecha)

Todo comienzo del último elemento de desorden, se ha burbujeando a la primera posición por delante del trastorno para que se ordena

function swap(A, i, j) {
    if (i === j) return
    [A[i], A[j]] = [A[j], A[i]]
}

function bubbleSort(A) {
    for (let i = 0, ii = A.length - 1; i < ii; i++) {
        let done = true
        for (let j = A.length - 1; j > i; j--) {
            if (A[j] < A[j - 1]) {
                swap(A, j, j - 1)
                done = false
            }
        }
        if (done) break
    }
}

2. Seleccione Ordenar

La matriz se divide en regiones ordenados (izquierda) y desordenada región (a la derecha)

De cada uno de trastorno en un elemento apropiado, y para intercambiar su posición a la primera región desordenada, de manera que se convierte en una ordenada

function swap(A, i, j) {
    if (i === j) return
    [A[i], A[j]] = [A[j], A[i]]
}

function selectionSort(A) {
    for (let i = 0, ii = A.length; i < ii; i++) {
        let minIdx = i
        for (let j = i, jj = A.length; j < jj; j++) {
            if (A[j] < A[minIdx]) minIdx = j
        }
        swap(A, i, minIdx)
    }
}

3, tipo de inserción

La matriz se divide en regiones ordenados (izquierda) y desordenada región (a la derecha)

Cada vez que el primer elemento de desorden en el área, se ha ordenado al área de intercambio de posición delantera, por lo que se ordena

function insertionSort(A) {
    for (let i = 1, ii = A.length; i < ii; i++) {
        let v = A[i]
        let j = i - 1
        while (j >= 0) {
            if (A[j] > v) {
                A[j + 1] = A[j]
                j -= 1
            } else break
        }
        A[j + 1] = v
    }
}

4, ordenamiento por mezcla

De forma recursiva, cada vez que la matriz se divide en dos, y después de dos matrices de clasificación, asocia dos arreglos

function mergeSort(arr) {
    if (arr.length <= 1) return arr
    let mid = Math.floor(arr.length / 2)
    let left = arr.slice(0, mid)
    let right = arr.slice(mid)
    return merge(mergeSort(left), mergeSort(right))
}

function merge(left, right) {
    let rs = [], lp = 0, rp = 0
    while (lp < left.length && rp < right.length)
        (left[lp] < right[rp]) ? rs.push(left[lp++]) : rs.push(right[rp++])
    while (lp < left.length)
        rs.push(left[lp++])
    while (rp < right.length)
        rs.push(right[rp++])
    return rs
}

Optimización: secuenciación In-situ, reduciendo así la nueva matriz

function mergeSortHelper(A, T, i, j) {
    if (i === j) return
    let m = Math.floor((i + j) / 2)
    mergeSortHelper(A, T, i, m)
    mergeSortHelper(A, T, m + 1, j)
    // merge
    for (let k = i; k <= j; k++) T[k] = A[k]
    let l = i, r = m + 1
    for (let curr = i; curr <= j; curr++) {
        if (l > m) A[curr] = T[r++]
        else if (r > j) A[curr] = T[l++]
        else if (T[l] < T[r]) A[curr] = T[l++]
        else A[curr] = T[r++]
    }
}

function mergeSort(A) {
    mergeSortHelper(A, [], 0, A.length - 1)
}

Optimización: matriz temporal última parte de inserción inversa, que no puede detectar el caso límite

function mergeSortHelper(A, T, i, j) {
    if (i === j) return
    let m = Math.floor((i + j) / 2)
    mergeSortHelper(A, T, i, m)
    mergeSortHelper(A, T, m + 1, j)
    // merge
    for (let k = i; k <= m; k++) T[k] = A[k]
    for (let k = 1; k <= j - m; k++) T[j - k + 1] = A[k + m]
    let l = i, r = j
    for (let curr = i; curr <= j; curr++) {
        if (T[l] < T[r]) A[curr] = T[l++]
        else A[curr] = T[r--]
    }
}

function mergeSort(A) {
    mergeSortHelper(A, [], 0, A.length - 1)
}

5, Ordenación rápida

De forma recursiva, cada vez que la selección de una referencia en la matriz, la matriz de acuerdo con la de referencia se divide en dos, y después de dos ordenadas matrices, las matrices y de empalme de dos de referencia

function quickSort(arr) {
    if (arr.length <= 1) return arr
    // find pivot
    let pivotIndex = Math.floor(arr.length / 2)
    let pivot = arr.splice(pivotIndex, 1)[0]
    // partition
    let left = arr.filter(item => item <= pivot)
    let right = arr.filter(item => item > pivot)
    // recursive
    return [...quickSort(left), pivot, ...quickSort(right)]
}

Optimización: secuenciación In-situ, reduciendo así la nueva matriz

function swap(A, i, j) {
    if (i === j) return
    [A[i], A[j]] = [A[j], A[i]]
}

function quickSortHelper(A, i, j) {
    if (j <= i) return
    // find pivot
    let pivotIndex = Math.floor((i + j) / 2)
    let pivot = A[pivotIndex]
    // put pivot at last
    swap(A, pivotIndex, j)
    // partition
    let l = i - 1
    let r = j
    do {
        while (A[++l] < pivot) {}
        while (l < r && pivot < A[--r]) {}
        swap(A, l, r)
    } while (l < r);
    // put pivot in place
    swap(A, j, l)
    // recursive
    quickSortHelper(A, i, l - 1)
    quickSortHelper(A, l + 1, j)
}

function quickSort(A) {
    quickSortHelper(A, 0, A.length - 1)
}

Optimización: el uso de reemplazo pila de recursión

function swap(A, i, j) {
    if (i === j) return
    [A[i], A[j]] = [A[j], A[i]]
}

function quickSortHelper(A, i, j) {
    let stack = []
    stack.push(i)
    stack.push(j)
    while (stack.length > 0) {
        j = stack.pop()
        i = stack.pop()
        // find pivot
        let pivotIndex = Math.floor((i + j) / 2)
        let pivot = A[pivotIndex]
        // put pivot at last
        swap(A, pivotIndex, j)
        // partition
        let l = i - 1
        let r = j
        do {
            while (A[++l] < pivot) {}
            while (l < r && pivot < A[--r]) {}
            swap(A, l, r)
        } while (l < r);
        // undo the last swap
        swap(A, l, r)
        // put pivot in place
        swap(A, l, j)
        // load up stack
        if (l - 1 > i) {
            stack.push(i)
            stack.push(l - 1)
        }
        if (j > l + 1) {
            stack.push(l + 1)
            stack.push(j)
        }
    }
}

function quickSort(A) {
    quickSortHelper(A, 0, A.length - 1)
}

6, el programa de prueba

var origin = Array.from({ length: 100000 }, x => Math.floor(Math.random() * 100000))
var arr4bubble = JSON.parse(JSON.stringify(origin))
var arr4selection = JSON.parse(JSON.stringify(origin))
var arr4insertion = JSON.parse(JSON.stringify(origin))
var arr4merge = JSON.parse(JSON.stringify(origin))
var arr4quick = JSON.parse(JSON.stringify(origin))

console.time('q')
quickSort(arr4quick)
console.timeEnd('q')

console.time('m')
mergeSort(arr4merge)
console.timeEnd('m')

console.time('i')
insertionSort(arr4insertion)
console.timeEnd('i')

console.time('s')
selectionSort(arr4selection)
console.timeEnd('s')

console.time('b')
bubbleSort(arr4bubble)
console.timeEnd('b')

[Leer más Estructura de Datos y Algoritmos serie de artículos, vistazo a las estructuras de datos y algoritmos de opinión ]

Supongo que te gusta

Origin www.cnblogs.com/wsmrzx/p/12545457.html
Recomendado
Clasificación