Algoritmo de ordenación Daquan (seleccionar, insertar, Colina, fusión, rápido) de Java, C, Python lograr

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

  1. Cada elemento de la matriz a partir de su posición final no están muy
  2. Una matriz ordenada por uno de la gran variedad de pequeña
  3. 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:

  1. Izquierda agotado, en la derecha
  2. El agotamiento del depósito de derecha, izquierda
  3. Gran dejó que la derecha, a la derecha
  4. 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

  1. Clasificar los datos de la matriz de entrada a la matriz auxiliar
  2. 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

  1. complejidad espacio no es óptima
  2. En la práctica, no necesariamente encontrarse con el peor de los casos
  3. Además de otras acciones algoritmos de comparación (por ejemplo, acceso) también es muy importante
  4. 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)returnrevisado 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.

Supongo que te gusta

Origin www.cnblogs.com/endevelop-gw/p/12508038.html
Recomendado
Clasificación