Estrutura de dados: algoritmo de classificação comum (6): classificação rápida
1. Ideia básica:
Selecione um elemento de referência, geralmente o primeiro elemento ou o último elemento, por meio de uma rodada de varredura, a sequência a ser classificada é dividida em duas partes, uma é menor que o elemento de referência, a outra é maior ou igual ao elemento de referência e o elemento de referência é classificado nele Em seguida, use o mesmo método para classificar as duas partes recursivamente até que haja apenas um número em cada intervalo.
2. Exemplos
Exemplo: a matriz a [15] = {3,44,38,5,47,15,36,26,2,46,4,19,50,48} é classificada por classificação rápida
Fonte da imagem: https://www.cnblogs.com/zwtgyh/p/10631760.html
Código de exemplo:
//辅助函数:交换值
void exchange(int * a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
//打印数组函数
void print_arr(int *a, int size)
{
cout << "打印数组:";
for (int i = 0; i<size; i++) //打印数组
{
cout << a[i] << " ";
}
cout << endl << endl;
}
/*序列划分函数*/
int partition(int a[], int p, int r) {
int key = a[r];//取最后一个
int i = p - 1;
for (int j = p; j < r; j++)
{
if (a[j] <= key)
{
i++;
//i一直代表小于key元素的最后一个索引,当发现有比key小的a[j]时候,i+1 后交换
exchange(&a[i], &a[j]);
}
}
exchange(&a[i + 1], &a[r]);//将key切换到中间来,左边是小于key的,右边是大于key的值。
return i + 1;
}
void quickSort(int a[], int p, int r) {
int position = 0;
if (p<r)
{
position = partition(a,p,r);//返回划分元素的最终位置
quickSort(a,p,position-1);//划分左边递归
quickSort(a, position + 1,r);//划分右边递归
}
}
//主函数
void main() {
int a[15]={3,44,38,5,47,15,36,26,2,46,4,19,50,48};
cout << "输入数组 a[15]={3,44,38,5,47,15,36,26,2,46,4,19,50,48} " << endl;
quickSort(a, 0, 14);
print_arr(a, 15);
}
3. Resumo:
- O melhor caso: cada rodada de divisão divide a sequência a ser ordenada em duas partes, de modo que o tempo necessário para cada parte é 1/2 da rodada anterior. Se uma sequência de n elementos for classificada, a profundidade da árvore de recursão é [logn] +1, o que significa que apenas recursões logn são necessárias e o tempo total necessário é T (n), a primeira vez que você precisa verificar toda a sequência, fazer n comparações A sequência é dividida em duas, e as duas partes precisam de tempo T (n / 2) respectivamente, que são divididas em ordem: T (n) = 2 T (n / 2) + n T (n) = 2 (2 * (T (n / 4) + n / 2) + n = 4 T (n / 4) + 2n e assim por diante, e T (1) = 0, então T (n) = n T (1) + n * logn = O (nlogn)
- Pior caso: quando a sequência a ser ordenada é uma sequência ordenada (positiva ou reversa), a situação obtida após cada divisão é que há 1 elemento de um lado e os elementos restantes do outro lado e, finalmente, n-1 rodadas de looping , E o i-ésimo ciclo precisa de ni comparações, o número total de comparações é n-1 + n-2 + ... + 1 = n (n-1) / 2, ou seja, a complexidade do tempo é O (n ^ 2)
- A classificação rápida é uma classificação in-situ e não requer espaço de memória adicional.
- A classificação rápida não é uma classificação estável, ela destruirá a estabilidade durante o processo de troca.