secuencia
La secuenciación sencilla
hipótesis
determinación Tamaño se han definido; determinar si ordenó; cambiando el orden de estas tres funciones
en el presente documento como notas "algoritmo", Java desde el libro de códigos
selección Ordenar
Encontrar el elemento más pequeño de la gama, el primer elemento y cambiarlo (si es el primer elemento, el intercambio en sí y en sí). Una vez más, encontrar el elemento más pequeño en el resto de los elementos, se intercambiará con el segundo elemento. Y así sucesivamente, hasta que se ordena toda la matriz.
El tiempo de ejecución es independiente de la entrada, incluso si se ha pedido matriz, que todavía tiene que continuar a través de la matriz.
movimiento mínimo de datos, para cambiar cada vez que los dos valores de los elementos de la matriz, así seleccionados para la clasificación de N veces la de cambio, una relación lineal con el tamaño de la matriz.
Código de ejemplo:
public class Selection
{
public static void sort(Comparable[] a)
{//将a升序排列
int N=a.length;
for(int i=0;i<N;i++)
{//将a[i]和a[i+1..N]中最小的元素交换
int min=i;
for(int j=i+1;j<N;j++)
if (less(a[j],a[min]))min=j;
exch(a,i,min)
}
}
}
void sort(Comparable *a,int asize)
{
{//将a升序排列
int N=aSize;
for(int i=0;i<N;i++)
{//将a[i]和a[i+1..N]中最小的元素交换
int min=i;
for(int j=i+1;j<N;j++)
if (less(a[j],a[min]))min=j;
exch(a,i,min)
}
return 0;
}
def sort(a):
N=len(a)
for i in range(N):
min=i
for j in range(i+1,N):
if (less(a[j],a[min])):
min=j;
exch(a,i,min)
Ordenar la inserción
Un elemento se inserta en los elementos ya ordenados. Cuando el índice alcanza la matriz más a la derecha, la clasificación final.
El tiempo de funcionamiento depende de la secuencia de entrada inicial de elementos, cuando la matriz está muy cerca ordenó, correr más rápido.
Ejemplo de código
public class Insertion
{
public static void sort(Comparable[] a)
{//将a升序排列
int N=a.length;
for(int i=1;i<N;i++)
{//将a[i]插入到a[i-1],a[i-2],a[i-3]...中
for(int j=i;j>0&&less(a[j],a[j-1];j--))
exch(a,j,j-1);
}}
}
void Insertion(Comparable *a,int aSize)
{ //将a升序排列
int N=aSize;
for(int i=1;i<N;i++)
{//将a[i]插入到a[i-1],a[i-2],a[i-3]...中
for(int j=i;j>0&&less(a[j],a[j-1]);j--)
exch(a,j,j-1);
}
}
def Insertion(a):
N=len(a)
for i in range(N):
j=i
while(j>0 and less(a[j],a[j-1])):
exch(a,j,j-1)
cuando
- Cada elemento de la matriz a partir de su posición final no están muy
- Una matriz ordenada por uno de la gran variedad de pequeña
- Sólo unos pocos elementos de la matriz no están colocados correctamente
La inserción de velocidad algoritmo puede ser el más rápido de todos los algoritmos.
Mientras el bucle interior elementos más grandes se mueven a la derecha en vez del intercambio de dos elementos, la velocidad será más rápido.
Comparable temp=a[i]
for(int j=i;j>0&&less(a[j],a[j-1]);j--)
{a[j]=a[j-1];int u=j}
a[u]=temp;
la ordenación Shell
Colina clasificación basada en la ordenación por inserción. Inserción tipo, a un elemento en la posición correcta para ir a través de un máximo de N-1 veces (ya que sólo se puede mover una posición)
En la colina de la clasificación, el primer intercambio de elementos no adyacentes para lograr orden local, y luego el orden local de la matriz está ordenada.
Shell tipo de pensamiento es hacer que la matriz de intervalo es una matriz de h se ordena. La matriz de una [0,1,2,3..N-1], de modo que a [0, h, 2h, ..], a [1, h + 1,2-h + 1, ..], .. ordenado
Colina clasificación combinación de tamaño y el orden de la matriz puede ser visto como una inserción incremental de tipo no es 1.
h no es necesario tener un factor de N, ni siquiera si hay un poco de "atención" inicial para el elemento al final h es 1, se convertirá en un factor.
Código es el siguiente:
public class shell
{
public static void sort(Comparable[] a)
{
int N=a.length;
int h=1;
while(h<N/3)h=3*h+1;//1,4,13,40,...
while(h>=1)
{//将数组变为h有序
for(int i=h;i<N;i++)
{//将a[i]插入到a[i-h],a[i-2h],a[i-3h]中去
for(int j=i;j>=h&&less(a[j],a[j-h]));j-=h)
exch(a,j,j-h);
}
h=h/3;
}
}
}
void sort(Comparable *a,int asize)
{
int N=aSize;
int h=1;
while(h<N/3)h=3*h+1;//1,4,13,40,...
while(h>=1)
{//将数组变为h有序
for(int i=h;i<N;i++)
{//将a[i]插入到a[i-h],a[i-2h],a[i-3h]中去
for(int j=i;j>=h&&less(a[j],a[j-h]));j-=h)
exch(a,j,j-h);
}
h=h/3;
}
}
def sort(a):
int N=len(a)
int h=1
while(h<N/3):
h=3*h+1
while(h>=1):
j=i
for i in range(h,N):
while(j>=h and less(a[j],a[j-h])):
j-=h
exch(a,j,j-h)
h=h//3
Colina clasificación de velocidad depende de la elección de la secuencia h, alguna secuencia compleja puede tener un mejor rendimiento.
Combinar especie
Los dos arreglos ordenados se funden en una matriz más grande
La satisfacción de tiempo complejidad O ($ logN $), el espacio adicional requerido es proporcional a N
lugar fusión
La idea es construir un simple fusión de la tercera serie, se utiliza para mantener los resultados de dos conjuntos ordenados. Sin embargo, en el proceso de clasificación, que requieren múltiples de combinación. Si usted tiene más de uno se fusionan para crear una matriz, que consumen gran espacio. Por lo tanto, teniendo lugar un algoritmo de fusión.
public static void merge(Comparable[] a,int lo,int mid,int hi )
{//将a[lo..mid]和a[mid+1,hi]归并
int i=lo,j=mid+1;
for(int k=lo;k<=hi;k++)//将a[lo..hi]复制到aux[lo..hi]
aux[k]=a[k];
for(int k=lo;k<=hi;k++)
if(i>mid) a[k]=aux[j++];
else if(j>hi) a[k]=aux[i++];
else if(less(aux[j],aux[i])) a[k]=aux[j++];
else a[k]=aux[i++];
}
void merge(Comparable *a,int lo,int mid,int hi)
{ //将a[lo..mid]和a[mid+1,hi]归并
int i=lo,j=mid+1;
for(int k=lo;k<=hi;k++)//将a[lo..hi]复制到aux[lo..hi]
aux[k]=a[k];
for(int k=lo;k<=hi;k++)
if(i>mid) a[k]=aux[j++];
else if(j>hi) a[k]=aux[i++];
else if(less(aux[j],aux[i])) a[k]=aux[j++];
else a[k]=aux[i++];
}
def merge(a,lo,mid,hi):
i=lo
j=mid+1
aux=a[:]
for i in range(lo,hi):
if i>mid:
a[k]=aux[j]
j+=1
elif j>hi:
a[k]=aux[i]
i+=1
elif less(aux[j],aux[i]):
a[k]=aux[j]
j+=1
else:
a[k]=aux[i]
i+=1
Lo que significa más de cuatro jueces fueron:
- Izquierda agotado, en la derecha
- El agotamiento del depósito de derecha, izquierda
- Gran dejó que la derecha, a la derecha
A la derecha que en la izquierda gran depósito de izquierda
De arriba hacia abajo de combinación especie
Si una función puede estar dispuesto en dos sub-series, entonces se puede combinar dos sub-series de toda la matriz especie
public class Merge
{
private static Comparable[] aux;
public static void sort (Comparable[] a)
{
aux=new Comparable[a.length];
sort(a,0,a.length-1);
}
private static void sort (Comparable[] a,int lo,int hi)
{//将数组a[lo..hi]排序
if(hi<=mid>)return;
int mid=lo+(hi-mid)/2;
sort(a,lo,mid);//排序左半边
sort(a,mid+1,hi);//排序右半边
merge(a,lo,mid,hi);//归并结果(见“原地归并排序”)
}
}
void sort (Comparable *a,int lo,int hi,int aSzie)
{
if(hi<=mid>)return;
int mid=lo+(hi-mid)/2;
sort(a,lo,mid);//排序左半边
sort(a,mid+1,hi);//排序右半边
Comparable *a=(Comparable *)malloc(sizeof(Comparable)*aSize);
merge(a,lo,mid,hi);//归并结果(见“原地归并排序”)
}
def sort(a,lo,hi):
if(hi<=mid>):
return;
mid=lo+(hi-mid)/2
sort(a,lo,mid)
sort(a,mid+1,hi)
merge(a,lo,mid,hi)
De pequeña escala sub-matriz puede utilizar la inserción de especie
Tiempos pueden reducirse de aproximadamente 10% - 15%
Se puede determinar si una matriz ordenada
El análisis de condiciones además de un [MID] es menor que una función [mediados + 1], y, en algunos casos puede omitir merge ()
No copie los elementos de la matriz secundaria
Esto se refiere a evitar la copia de un elemento de asistencia momento de la matriz, la matriz en sí no significa evitar secundario (que puede ahorrar tiempo, pero no se puede ahorrar espacio)
Hay dos maneras
- Clasificar los datos de la matriz de entrada a la matriz auxiliar
La matriz está ordenada de la entrada de datos auxiliares a la matriz
Desde la fusión algoritmo de abajo hacia arriba
Para combinar micro-matriz, y luego fusionar pequeña matriz y, a continuación, combinar matrices grandes, por lo que va
public class MergeBU
{
private static Comparable[] aux;
public static void sort(Comparable[] a)
{//进行lgN次归并
int N=a.length;
aux=new Comparable[N];
for(int sz=1;sz<N;sz=sz+sz)//sz子数组大小
for(int lo=0;lo<N-sz;lo+=sz+sz)//lo:子数组索引
merge(a,lo,lo+sz-1,Math.min(lo+sz+sz-1,N-1);
}
}
void sort(Comparable *a,int aSize)
{
int N=aSize;
Comparable *aux=(Comparable *)malloc(sizeof(Comparable)*N);
for(int sz=1;sz<N;sz=sz+sz)//sz子数组大小
for(int lo=0;lo<N-sz;lo+=sz+sz)//lo:子数组索引
merge(a,lo,lo+sz-1,min(lo+sz+sz-1,N-1);
}
def sort(a):
N=len(N)
aux=a[:]
while sz<N:
for lo in range(0,N-sz,sz*2):
merge(a,lo,lo+sz-1,min(lo+sz+sz-1,N-1))
sz+=sz
Cuando un objeto se consigue mediante la clasificación de la lista, sólo es necesario reorganizar la lista, que puede lograrse en la secuenciación situ
Combinar tipo de complejidad
Prueba matemática un poco, para conocer la complejidad del tiempo más rápido algoritmo de clasificación es O ($ NlogN $), no puede haber más pequeña de lo que es algoritmos
Pero todavía hay algunas limitaciones fusionan algoritmo
- complejidad espacio no es óptima
- En la práctica, no necesariamente encontrarse con el peor de los casos
- Además de otras acciones algoritmos de comparación (por ejemplo, acceso) también es muy importante
- Algunos también no se puede comparar la clasificación matriz
Ordenación rápida
Rápida requiere especie poco espacio y tiempo de la complejidad satisfacen O ($ logN $), pero en algunos casos la tasa se reduce a O (n ^ 2 $ $).
El algoritmo básico
ordenación rápida es un algoritmo de divide y vencerás, una matriz se divide en dos partes, las dos partes a continuación, ordenados por separado. Cuando los dos sub-series, ordenado y ordenados toda una serie de forma natural.
En el algoritmo de la fusión, la matriz se divide por igual en dos partes, el procesamiento recursivo antes de toda la matriz. En el tipo rápida, la posición de corte de la matriz depende de los contenidos de la matriz, la recursión se produce después de procesar toda la matriz.
código de implementación
public Class Quick
{
public static void sort(Comparable[] a)
{
StdRandom.shuffle(a);\
sort(a,0,a.length-1);
}
private static sort(Comparable[] a,int lo,int hi)
{
if(hi<=lo)return;
int j=partition(a,lo,hi);//切分,见“快速排序的切分”
sort(a,lo,j-1);
sort(a,j+1,hi);
}
}
void quciksort(int *a,int aSize)
{
StdRandom.shuffle(a);
sort(a,0,aSize);
}
void sort(int a*,int lo,int hi)
{
if(hi<=lo)return;
int j=partition(a,lo,hi);//切分,见“快速排序的切分”
sort(a,lo,j-1);
sort(a,j+1,hi);
}
def quicksort(a):
random.shuffle(a)
sort(a,0,a.length-1)
def sort(a,lo,hi):
if(hi<lo):
return
j=partition(a,lo,hi)
sort(a,lo,j-1)
sort(a,j+1,hi)
Por lo general, cortando algoritmo para seleccionar [Lo] Como elementos de división. Definir dos punteros, de izquierda a derecha, una derecha a izquierda, el puntero izquierdo cuando se encuentra con un elemento de mayor que o igual, menos un puntero derecho encontró sus elementos, intercambiados. Cuando el puntero dos se encuentran, devuelve una matriz de la izquierda a mayor el número correcto.
Si no puede entender las palabras, puede escribir varias gama simular este proceso.
la implementación del código:
private static int partition(Comparable[] a,int lo,int hi)
{//将数组切分为a[lo..i-1],a[i],a[i+1..hi]
int i=lo,j=hi+1;//左右扫描数组
Comparable v=a[0];//切分元素
while(true)
{//左右扫描,检查扫描是否结束并交换元素
while(less(a[++i],v))if(i==hi)break;
while(less(v,a[--j]))if(j==lo)break;
if(i>=j)break;
exch(a,i,j);
}
exch(a,lo,j);//将v=a[j]放到正确的位置
return j;
}
int partition(int a*,int lo,int hi)
{//将数组切分为a[lo..i-1],a[i],a[i+1..hi]
int i=lo,j=hi+1;//左右扫描数组
Comparable v=a[0];//切分元素
while(true)
{//左右扫描,检查扫描是否结束并交换元素
while(less(a[++i],v))if(i==hi)break;
while(less(v,a[--j]))if(j==lo)break;
if(i>=j)break;
exch(a,i,j);
}
exch(a,lo,j);//将v=a[j]放到正确的位置
return j;
}
def partition(a,lo,hi):
i=lo
j=hi+1
v=a[0]
while(ture):
while(less(a[i],v)):
a[i]+=1
if(i==hi):
break
while(less(v,a[j])):
a[j]-=1
if(j==lo):
break
if(i>=j):
break
exch(a,i,j)
exch(a,lo,j)
return j
lugar en rodajas
Si crea una matriz secundaria a ser segmentada, copiar de nuevo el costo puede superar los beneficios.
No transfronteriza
Cuidadosamente límites de la matriz de punteros tiro
aleatoriedad mantener
Al principio molesta a favor de la rápida-ordenar una matriz
Terminator Cycle
Elementos tales como la segmentación y el mismo valor puede ocurrir, consideran
elemento de procesamiento de segmentación tiene una duplicación de
El método anterior puede aparecer intercambio equivalente, pero evitar la complejidad tiempo se reduce a la plaza del nivel
La terminación de recursiva
Uso racional de los elementos de segmentación, para asegurar que los elementos de segmentación se colocan en la posición correcta
algoritmo de mejora
La ordenación por inserción a la conmutación
Cuando un pequeño número de columnas, se puede utilizar la ordenación rápida
será if(hi<=lo)return
revisado paraif(hi<=lo+M){Insertion.sort(a,lo,hi);return}
Tres muestras de segmentación
El uso de la parte mediana de los elementos sub matriz como puede ser mejores resultados de segmentación, pero requiere la pérdida del tiempo de cálculo mediana. General estimó que el tamaño de la muestra es de 3 mejor efecto.
El mejor tipo de entropía
Algunos elementos de la matriz contiene una gran cantidad de repetición, pero todavía tendrán que resolver rápida especie puede ser modificado de manera apropiada.
Por ejemplo tres segmentación matriz se divide en mayor que, igual a, menor que la porción de los elementos de rebanada.
Interesados pueden buscar tutorial detallado por su cuenta, sólo para adjuntar el código de Java
public class Quick3way
{
private static void sort(Comparable[] a,int lo,int hi)
{
if(hi<=lo)return;
int lt=lo,i=lo+1,gt=hi;
Comparable v=a[lo];
while(i<=gt)
{
int cmp=a[i].compareTo(v);
if(cmp<0)exch(a,lt++,i++);
else if(cmp>0)exch(a,i,gt--);
else i++;
}
sort(a,lo,t-1);
sort(a,gt+1,hi);
}
}
Algunos otros contenidos en la secuencia de prioridad, no se puede considerar completamente ordenados, y aún más después de ella.