Tipo de algoritmo de classificação de mesclagem
A classificação de fusão é uma das aplicações da estratégia de dividir e conquistar, dividir e conquistar.
A complexidade do tempo é O (n log n)
. A ideia da classificação por mesclagem é: dividir a fila em subfilas até que seja indivisível e, em seguida, mesclar as subseqüências para obter uma seqüência completamente ordenada; ou seja, primeiro faça com que cada subseqüência tenha Ordene e, em seguida, faça os segmentos de sub-sequência ordenadamente.
testemunho
O núcleo do merge sort é
分治思想
e递归实现
- Estratégia de divisão e conquista: decomponha o problema original em vários subproblemas menores, mas semelhantes, resolva esses subproblemas recursivamente e então mescle as soluções dos subproblemas para estabelecer a solução do problema original.
Sem imagem, sem verdade, fluxograma de classificação de mesclagem (pirata Baidu Baike?)
Análise de Algoritmos
- Primeiro decomponha a fila recursivamente (usando decomposição de ponto médio) até que o número de elementos na fila seja 1
- A fila de decomposição é dividida em fila esquerda (baixa, média) e fila direita (média + 1, alta) calculando o ponto médio da fila
- Quando a fila original é dividida na menor fila (há apenas um elemento na fila), as subfilas são ordenadas
- Combine duas filas ordenadas em uma fila ordenada, o
mergeArray
método no código
Código
Os comentários são mais detalhados, então não vou entrar em detalhes
/**
*
* @param array 排序数组
* @param start 开始位置
* @param end 结束位置
*/
private void mergeSort(int[] array, int start, int end) {
if (start < end) {
//当数组中的元素不可分时,停止分解
int mid = (start + end) / 2;//计算中间坐标
mergeSort(array, start, mid);//递归分解数组
mergeSort(array, mid + 1, end);//递归分解数组
//合并数组,合并后为有序数组
//因为前面为递归调用,所以可以保证第一次调用此方法时,子数组长度为1
mergeArray(array, start, mid, end);
}
}
private void mergeArray(int[] array, int start, int mid, int end) {
int[] left = new int[mid - start + 1 //存放数据长度
+ 1];//预留安全守卫
int[] right = new int[end - mid//存放数据长度
+ 1];//预留安全守卫
System.arraycopy(array, start, left, 0, left.length - 1);
System.arraycopy(array, mid + 1, right, 0, right.length - 1);
left[left.length - 1] = SAFE_GUARD;
right[right.length - 1] = SAFE_GUARD;
int l = 0, r = 0;
for (int i = start; i <= end; i++) {
if (right[r] == SAFE_GUARD) {
array[i] = left[l];
}
if (left[l] == SAFE_GUARD) {
array[i] = right[r];
}
if (left[l] <= right[r]) {
array[i] = left[l];
l++;
} else {
array[i] = right[r];
r++;
}
}
}
Conclusão
Pessoalmente, acho que o importante sobre a fusão e a classificação é a ideia de dividir para conquistar.
JDK7
Aplicativos introduzidos queForkJoinPool
também são estratégias de dividir e conquistar. Nesse caso, você precisa entender a estratégia de dividir para conquistar!
O segundo dia de "Introdução aos Algoritmos", vamos! Próximo分治策略