12. Combinar ordenar

Ordenar fusión

Primero divida la matriz del medio en dos partes, y luego ordene las dos partes por separado, y luego combine las dos partes en orden, de modo que toda la matriz esté ordenada

Divide la mente, divide y gobierna.

Dividir y conquistar es un pensamiento para resolver problemas, la recursividad es una habilidad de programación

Fórmula recursiva:

merge_sort (p ... r) = merge (merge_sort (p ... q), merge_sort (q + 1 ... r))

Condición de terminación: p> = r ya no necesita continuar la descomposición

Pseudocódigo:

// 归并排序算法, A 是数组,n 表示数组大小
merge_sort(A, n) {
  merge_sort_c(A, 0, n-1)
}

// 递归调用函数
merge_sort_c(A, p, r) {
  // 递归终止条件
  if p >= r  then return

  // 取 p 到 r 之间的中间位置 q
  q = (p+r) / 2
  // 分治递归
  merge_sort_c(A, p, q)
  merge_sort_c(A, q+1, r)
  // 将 A[p...q] 和 A[q+1...r] 合并为 A[p...r]
  merge(A[p...r], A[p...q], A[q+1...r])
}

Proceso de análisis:

1. Solicite una matriz temporal tmp con el mismo tamaño que A [p ... r].

2. Usamos dos cursores i y j para señalar el primer elemento de A [p ... q] y A [q + 1 ... r], respectivamente.

3. Compare estos dos elementos A [i] y A [j], si A [i] <= A [j], colocamos A [i] en la matriz temporal tmp, y me desplazamos por uno, De lo contrario, coloque A [j] en la matriz tmp y desplace j hacia atrás.

4. Repita el proceso anterior hasta que una matriz esté terminada, y luego coloque los elementos en otra matriz a su vez.

5. Finalmente, copie los datos en la matriz temporal tmp a la matriz original A [p ... r] ...

Estabilidad : clasificación estable,

Complejidad del tiempo:

T (1) = C; cuando n = 1, solo se necesita tiempo de ejecución de nivel constante, por lo que se expresa como C.

T (n) = 2 * T (n / 2) + n ; n> 1

T(n) = 2*T(n/2) + n
     = 2*(2*T(n/4) + n/2) + n = 4*T(n/4) + 2*n
     = 4*(2*T(n/8) + n/4) + 2*n = 8*T(n/8) + 3*n
     = 8*(2*T(n/16) + n/8) + 3*n = 16*T(n/16) + 4*n
     ......
     = 2^k * T(n/2^k) + k * n
     ......

T (n) = 2 ^ kT (n / 2 ^ k) + kn。

Cuando T (n / 2 ^ k) = T (1), es decir n / 2 ^ k = 1, obtenemos k = log2n. Sustituimos el valor de k en la fórmula anterior para obtener T (n) == Cn + nlog2n. Si usamos la notación O grande, T (n) es igual a O (nlogn) .

La eficiencia de ejecución no tiene nada que ver con el orden de la matriz original que se va a ordenar, por lo que su complejidad temporal es muy estable. Ya sea el mejor caso, el peor caso o el caso promedio, la complejidad temporal es O (nlogn).

Complejidad del espacio : es necesario abrir una matriz con un espacio temporal de n, por lo que la complejidad del espacio es O (n) , una debilidad fatal.

Darse cuenta:

package main

import "fmt"

func main() {
	arr := []int{8, 9, 5, 7, 1, 2, 5, 7, 6, 3, 5, 4, 8, 1, 8, 5, 3, 5, 8, 4}
	tempArr := mergeSort(arr)
	fmt.Println(tempArr)
}

/**
归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用
分治思想,时间复杂度为:O(n*log(n))
*/

func mergeSort(arr []int) []int {
	if len(arr) < 2 {
		return arr
	}
	i := len(arr) / 2
	left := mergeSort(arr[0:i])
	right := mergeSort(arr[i:])
	tempArr := merge(left, right)
	return tempArr
}

func merge(left, right []int) []int {
	tempArr := make([]int, 0)
	m, n := 0, 0 // left和right的index位置
	l, r := len(left), len(right)
	for m < l && n < r {
		if left[m] > right[n] {
			tempArr = append(tempArr, right[n])
			n++
			continue
		}
		tempArr = append(tempArr, left[m])
		m++
	}
	tempArr = append(tempArr, right[n:]...) // 这里竟然没有报数组越界的异常?
	tempArr = append(tempArr, left[m:]...)
	return tempArr
}

 

127 artículos originales publicados · Me gusta 24 · Visitas 130,000+

Supongo que te gusta

Origin blog.csdn.net/Linzhongyilisha/article/details/100110826
Recomendado
Clasificación