Diagrama y código del método de clasificación interno

Diagrama y código del método de clasificación interno

1. Clasificación por inserción directa

La ordenación por inserción directa es un método de ordenación simple. El método específico es: al insertar el registro i-ésimo, R1, R2, ..., Ri-1 ya están ordenadas, y luego la palabra clave Ki de Ri va seguida de la palabra clave Ki -1, Ki-2, etc. se comparan para encontrar la posición que se debe insertar e insertar Ri. La posición de inserción y los siguientes registros se mueven hacia atrás sucesivamente.

Insertar diagrama de clasificación directamente

void Insertsort(int data[],int n)
/*将数组data[0]~data[n-1]中的n个整数按非递减有序的方式进行排列*/
{
int i,j;
int tmp;
for(i=1;i<n;i++)
  if(data[i]<data[i-1]){
    tmp=data[i];
    data[i]=data[i-1];
    for(j=i-1;j>=0&&data[j]>tmp;j--)
      data[j+1]=data[j];
    data[j+1]=tmp;
  }
}

2. Clasificación de burbujas

El método de clasificación de burbujas para n registros es: primero compare la clave del primer registro con la clave del segundo registro, si está en el orden inverso, intercambie los valores de los dos registros y luego compare el segundo registro Y la palabra clave del tercer registro, y así sucesivamente, hasta que se compare la posición de la palabra clave del registro n-1 y el registro n. El proceso anterior es la primera clasificación de burbujas y el resultado es que el registro con la clave más grande se cambia a la posición del registro n. Luego se realiza la segunda clasificación de burbujas y la misma operación se realiza en los primeros registros n-1. Como resultado, el registro con la segunda clave más grande se cambia a la posición del registro n-1. Como máximo n-1 veces, todos los registros están ordenados. Si no hay procesamiento de intercambio de elementos en posiciones adyacentes en un proceso de clasificación de burbujas, el proceso de clasificación puede finalizar.

Diagrama de clasificación de burbujas 1
Diagrama de clasificación de burbujas 2

3. Orden de selección simple

El método básico para la selección y ordenación simple de n registros es seleccionar el registro con la clave más pequeña de n-i + 1 registros comparando ni (1 <= i <= n) entre palabras clave secundarias, y Intercambie con el registro i-ésimo. Cuando i es igual an, todos los registros están ordenados.

Diagrama de clasificación de selección simple

void SelectSort(int data[],int n)
/*将数组data中的n个整数按非递减有序的方式进行排序*/
{ 
int i,j,k,tmp;
for(i=0;i<n-1;i++){
  k=i;
  for(j=i+1;j<n;j++)  /*找出最小关键字的下标*/
    if(data[j]<data[k])
      k=j;
    if(k!=i){
      tmp=data[i];
      data[i]=data[k];
      data[k]=tmp;
    }
  }
}

4. Tipo de colina

La clasificación de colinas también se denomina "reducción de la clasificación incremental", que es una mejora del método de clasificación por inserción directa.
La idea básica de la clasificación Hill es: primero divida la secuencia completa de registros que se clasificarán en varias subsecuencias, y luego realice la clasificación de inserción directa respectivamente. Cuando los registros de la secuencia completa estén básicamente en orden, luego realice una clasificación de inserción directa en todos los registros. El método específico es: primero tomar un número entero d1 menor que n como primer incremento, dividir todos los registros del archivo en grupos d1, es decir, poner todos los registros cuya distancia sea múltiplo de d1 en el mismo grupo, y proceder en cada grupo Inserte la clasificación directamente; luego tome el segundo incremento d2 (d2 <d1), repita el trabajo de agrupación y clasificación anterior, y así sucesivamente, hasta que el incremento tomado di = 1 (di <di-1 <... d2 <d1) , Es decir, todos los registros se colocan en el mismo grupo para la ordenación por inserción directa.

Diagrama de clasificación de colinas

void ShellSort(int data[],int n)
{int *delta,k,i,t,dk,j;
 k=n;
 /*从k=n开始,重复k=k/2运算,直到k=1,所得k值的序列作为增量序列存入delta*/
 i=0;
 do{
   k=k/2;
   delta[i++]=k;
 }while(k>1);
 i=0;
 while((dk=delta[i])>0){
   for(k=delta[i];k<n;++k)
     if(data[k]<data[k-dk]){  /*将元素data[k]插入到有序增量子表中*/
       t=data[k];             /*备份待插入的元素,空出一个元素位置*/
       for(j=k-dk;j>=0 && t<data[j];j-=dk)
         data[j+dk]=data[j];  /*寻找插入位置的同时元素后移*/
       data[j+dk]=t;          /*找到插入位置,插入元素*/
     }
   ++i;                       /*取下一个增量值*/
 }
}

5. Combinar ordenación

La denominada "fusión" se refiere a la fusión de dos o más documentos ordenados en un nuevo documento ordenado. Una forma de implementar la ordenación por combinación es tratar un archivo desordenado con n registros como un archivo compuesto por n subarchivos ordenados de longitud 1, y luego fusionar por pares para obtener n / 2 de longitud 2 O un archivo ordenado de 1, y luego fusionar dos por dos, y repetir, hasta que se forme el archivo ordenado final que contiene n registros. Este método de clasificación de combinar repetidamente dos archivos ordenados en un archivo ordenado se denomina clasificación de combinación bidireccional.

La operación principal de la ordenación por fusión bidireccional es fusionar dos secuencias ordenadas adyacentes en una matriz unidimensional en una secuencia ordenada.

Fusionar diagrama de ordenación

void Merge(int data[],int s,int m,int n){
/*将分别有序的data[s..m]和data[m+1..n]归并为有序的data[s..n]*/
int i,start=s,k=0;
int *temp;
temp=(int *)malloc((n-s+1)*sizeof(int));  /*辅助空间*/
for(i=m+1;s<=m && i<=n;++k)               /*将data[s..m]与data[m+1..n]归并后存入temp*/
  if(data[s]<data[i])
    temp[k]=data[s++];
    else temp[k]=data[i++];
for(;s<=m;++k)                           /*将剩余的data[s..m]复制到temp*/
    temp[k]=data[s++];
for(i=0;i<k;i++)
    data[start++]=temp[i];
free(temp);
}
void MSort(int data[],int s,int t){  /*对data[s..t]进行归并排序*/
{
int m;
if(s<t){                            /*将data[s..t]均分为data[s..m]和data[m+1..t]*/
  m=(s+t)/2;
  MSort(data,s,m);                 /*递归地对data[s..m]进行归并排序*/
  MSort(data,m+1,t);               /*递归地对data[m+1..t]进行归并排序*/
  Merge(data,s,m,t);               /*将data[s..m]和data[m+1..t]归并为data[s..t]*/
  }
}

6. Clasificación rápida

La idea básica de la clasificación rápida es: dividir los registros que se van a clasificar en dos partes independientes, llamadas la primera mitad del área y la segunda mitad del área, mediante una pasada de clasificación. La clave del registro en la primera mitad del área no es mayor que la clave de la segunda mitad del área. Palabras, y luego continúe ordenando rápidamente las dos partes de los registros por separado, de modo que toda la secuencia esté ordenada.
El proceso de clasificación rápida se denomina división y el método específico consiste en adjuntar dos variables indicadoras de posición i y j, cuyos valores iniciales apuntan al primer registro y al último registro de la secuencia, respectivamente. Suponga que la clave del registro pivote (generalmente el primer registro) es pivote, luego busque primero hacia atrás desde la posición apuntada por j, y mueva el registro hacia atrás a la posición j cuando se encuentre el primer registro con una clave menor que pivote Consulte la posición, repita el proceso hasta que i y j sean iguales.

Diagrama de clasificación rápida

int partition(int data[],int low,int high)
/*用date[low]作为枢轴元素pivot进行划分*/
/*使得data[low..i-1]均不大于pivot,data[i+1..high]均不小于pivot*/
{int i,j;
int pivot;
pivot=data[low];
i=low; j=hight;
while(i<j){          /*从数组的两端交替向中间扫描*/
  while(i<j && data[j]>=pivot)
    j--;
  data[i]=data[j];  /*比枢轴元素小者往前移*/
  while(i<j && data[i]<=pivot)
    i++;
  data[j]=data[i];  /*比枢轴元素大者往后移*/
  }
data[i]=pivot;
return i;
}
void quickSort(int data[],int low,int high)
/*用快速排序方法对数组元素data[low..high]作非递减排序*/
{
if(low<high){
  int loc=partition(data,low,high)      /*进行划分*/
  quickSort(data,low,loc-1);            /*对前半区进行快速排序*/
  quickSort(data,loc+1,high);           /*对后半区进行快速排序*/
  }
}

7. Ordenar montón

La idea de la clasificación del montón: para ordenar un grupo de palabras clave, primero colóquelas en una secuencia de acuerdo con la definición del montón (es decir, establezca el montón inicial), de modo que se pueda generar la clave más grande en la parte superior del montón (para un montón raíz grande) y luego la Las palabras clave restantes se ajustan a una nueva pila y se obtiene la siguiente palabra clave más grande, y así sucesivamente, hasta que todas las palabras clave se organizan en una secuencia ordenada.
El método para establecer el montón inicial es colocar las palabras clave que se clasificarán en los nodos de un árbol binario completo (en este momento, el árbol binario completo no tiene necesariamente las características de un montón). Obviamente, todo i> (n / 2) El nodo Ki no tiene nodos secundarios. El subárbol enraizado en dicho Ki ya es un montón, por lo que el montón inicial se puede construir a partir del i-ésimo (i = (n / 2)) nodo Ki del árbol binario completo. , Haga gradualmente que el subárbol enraizado en K (n / 2), K (n / 2) -1, K (n / 2) -2, ..., K2, K1 cumpla con la definición de montón.
En el proceso de construir un montón para el subárbol enraizado en Ki, puede ser necesario intercambiar los valores de Ki y K2i (o K2i + 1). Como resultado, el subárbol enraizado en K2i (o K2i + 1) ya no puede satisfacer La definición de pilote debe continuar ajustándose con K2i (o K2i + 1) como raíz, y de esta manera iterativa, puede extenderse al nodo hoja. Este método es como tamizar, filtrar las palabras clave más grandes (o más pequeñas) capa por capa y finalmente generar el elemento más grande (o más pequeño) en la parte superior del montón.

Secuencia original Secuencia original
Construye el montón inicial (montón raíz grande)
El establecimiento del diagrama 1 del montón inicial (montón raíz grande)
El establecimiento del diagrama de montón inicial (montón raíz grande) 2
Diagrama de clasificación de montón

void HeapAdjust(int data[],int s,int m)
/*在data[s..m]所构成的一个元素序列中,除了data[s]外,其余元素均满足大根堆的定义*/
/*调整元素data[s]的位置,使data[s..m]成为一个大根堆*/
{
int tmp,j;
tmp=data[s];                 /*备份元素data[s],为其找到适当位置后再插入*/
for(j=2*s+1;j<=m;j=j*2+1){   /*沿值较大的孩子结点想下筛选*/
  if(j<m && data[j]<data[j+1])
    ++j;                     /*j是值较大的元素的下标*/
  if(tmp>=data[j])
    break;
  data[s]=data[j];  s=j;     /*用s记录待插入元素的位置(下标)*/
  }
data[s]=tmp;                 /*将备份元素插入由s所指出的插入位置*/
}
void HeapSort(int data[],int n)
/*数组data[0..n-1]中的n个元素进行堆排序*/
{
  int i;  int tmp;
  for(i=n/2;i>=0;--i)        /*将data[0..n-1]调整为大根堆*/
    HeapAdjust(data,i,n-1);
  for(i=n-1;j>0;--i)
  {
    tmp=data[0];  data[0]=data[i];
    data[i]=tmp;             /*堆顶元素data[0]与序列末的元素data[i]交换*/
    HeapAdjust(data,0,i-1);  /*待排元素的个数减一,将data[0..i-1]重新调整为大根堆*/
  }
}

8. Resumen de los métodos de clasificación internos

Método de clasificación complejidad del tiempo Espacio auxiliar estabilidad
Insertar directamente O (n²) O (1) estable
Elección simple O (n²) O (1) Inestable
Ordenamiento de burbuja O (n²) O (1) estable
Tipo de colina O (n ^ 1.3) O (1) Inestable
Ordenación rápida O (nlogn) Iniciar sesión Inestable
Tipo de pila O (nlogn) O (1) Inestable
Combinar ordenación O (nlogn) En) estable

Supongo que te gusta

Origin blog.csdn.net/Doigt_/article/details/108606501
Recomendado
Clasificación