Dividir e conquistar: classificação de fusão
Dividir e conquistar: etapas gerais
- Decompor o problema original em vários subproblemas
- Resolver subproblemas recursivamente resolver cada subproblema
- Combine soluções de problemas para mesclar os resultados na solução de problema original
Mesclar classificação
Idéia básica: "Mesclar"
duas ou mais subseqüências ordenadas em uma seqüência ordenada. Na classificação interna, geralmente é usada a classificação de mesclagem bidirecional . Ou seja, os dois registros adjacentes são subsequências ordenadas.
Fluxo do algoritmo:
-
A variedade de
A[1,n]
problemas de agendamento decompostos emA[1,n/2]
eA[n/2 +1,n]
Agendamento -
Resolva recursivamente o subproblema para obter duas submatrizes ordenadas
-
Combine duas submatrizes ordenadas em uma matriz ordenada
Mesclar classificação: uma matriz de decomposição, propriedade manual resolvida em conjunto e classificação
O procedimento é o seguinte (de pequeno a grande porte):
void merge_sort(int *A, int L, int R, int *T){
if(R-L > 1){
int M = L + (R-L)/2; //划分
int l = L, m = M, i = L;
merge_sort(A, L, M, T); //递归求解
merge_sort(A, M, R, T); //递归求解
while(l<M || m<R){
if(m>=R || (l<M && A[l]<=A[m]))
T[i++] = A[l++]; //从左半数组复制到临时空间
else
T[i++] = A[m++]; //从右半数组复制到临时空间
}
for(i=L; i<R; i++) //从辅助空间复制回 A 数组
A[i] = T[i];
}
}
A complexidade de tempo de mesclar e classificar n registros é O (nlog 2 n). qual é:
- A complexidade de tempo de cada mesclagem é O (n);
- Um total de log 2 n passes são necessários.
exemplo:
Descrição do título
Dada a você uma sequência inteira de comprimento n. Use a classificação por mesclagem para classificar esta série da menor para a maior. E produza os números sequenciados em ordem.
Formato de entrada Existem
duas linhas de entrada, a primeira linha contém o inteiro n.
A segunda linha contém n inteiros (todos os inteiros estão no intervalo de 1 a 109), que representa toda a sequência de números.
Formato de
saída A saída é uma linha, contendo n inteiros, indicando uma seqüência classificada de números.
Intervalo de dados
1≤n≤100000
Exemplo de entrada:
5
3 1 2 4 5
Saída de amostra:
1 2 3 4 5
Código:
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1e6 + 10;
int q[N],T[N];
void merge_sort(int *A, int L, int R, int *T){
if(R-L > 1){
int M = L + (R-L)/2;
int l = L, m = M, i = L;
merge_sort(A, L, M, T);
merge_sort(A, M, R, T);
while(l<M || m<R){
if(m>=R || (l<M && A[l]<=A[m]))
T[i++] = A[l++];
else
T[i++] = A[m++];
}
for(i=L; i<R; i++)
A[i] = T[i];
}
}
int main(){
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d",&q[i]);
merge_sort(q, 0, n, T);
for (int i = 0; i < n; i++)
printf("%d ",q[i]);
return 0;
}