Estrutura de dados: algoritmo de classificação comum (6): classificação rápida (implementação C ++)

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

img

img

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.

Acho que você gosta

Origin blog.csdn.net/qq_43801020/article/details/108137304
Recomendado
Clasificación