Sorting algorithm Daquan (select, insert, Hill, merge, fast) java, C, python achieve

Sequence

Simple Sequencing

Hypothesis

Size determination have been defined; determining whether ordered; changing the order of these three functions
herein as "algorithm" notes, java from the code book

Selection Sort

Find the smallest element in the array, the first element and exchange it (if it is the first element, the exchange itself and itself). Again, find the smallest element in the rest of the elements, it will exchange with the second element. And so forth, until the entire array is sorted.
Run time is independent of input, even if ordered array, it still needs to continue through the array.
Minimal data movement, to change every time the two values of the array elements, thus selected for sorting N times the exchange, a linear relationship with the size of the array.
Sample code:

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)

Insertion Sort

An element is inserted into the already ordered elements. When the index reaches the rightmost array, sorting the end.

Run time depends on the initial input sequence of elements, when the array is very close ordered, run faster.

Sample Code

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)

when

  1. Each element in the array from its final position are not far
  2. An ordered array by one of the large array of small
  3. Only a few elements in the array is not positioned correctly

Insertion algorithm speed may be the fastest of all algorithms.

As long as the inner loop larger elements are moved to the right rather than the exchange of two elements, the speed will be faster.

    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;

Shell sort

Hill sorting based on insertion sort. Insertion sort, to an element in the correct position to go through a maximum of N-1 times (as can only be moved one position)

In Hill sorting, the first exchange of non-adjacent elements to achieve local order, and then the local order of the array is sorted.
Shell sort of thinking is to make the interval array is an array of h is ordered. The array a [0,1,2,3..N-1], so that a [0, h, 2h, ..], a [1, h + 1,2h + 1, ..], .. ordered

Hill sorting combination of size and orderliness of the array can be seen as an incremental insertion sort is not 1.

h do not need to take a factor of N, not even if there is some initial "care" to the element at the end h is 1, it will become a factor.

code show as below:

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

Hill sorting speed depends on the choice of the sequence h, some complex sequence may have better performance.

Merge sort

The two ordered arrays merge into a larger array

Satisfying time complexity O ($ logN $), the additional space required is proportional to N

Place merging

The idea is to build a simple merger of the third array, used to hold the results of two ordered arrays. However, in the sorting process, we require multiple merge. If you have more than each merge to create an array, consuming huge space. Therefore, taking a place merging algorithm.

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

Meaning more than four judges were:

  1. Left exhausted, into the right
  2. The exhaustion of the right, left deposit
  3. Big left than the right, into the right
  4. To the right than the left large deposit left

    Top-down merge sort

    If a function can be arranged in two sub-arrays, then it can merge two sub-arrays of the entire array sort
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)

Small-scale sub-array can use insertion sort

Times can be reduced from about 10% - 15%

You can determine whether an orderly array

Analyzing conditions plus a [mid] is smaller than a [mid + 1], and in some cases can skip merge () function

Do not copy the elements to the secondary array

This refers to avoid copying a time assistance element to the array, the array itself does not mean avoiding secondary (which can save time, but you can not save space)
There are two ways

  1. Sort the data from the input array to the auxiliary array
  2. The array is sorted from the auxiliary data input to the array

    Since merging algorithm bottom-up

    To merge micro-array, and then merge small array, and then merge large arrays, so it goes
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

When an object is achieved by sorting the list, only need to reorganize the list, can be achieved in situ sequencing

Merge sort of complexity

Mathematical proof a little, to know the fastest sorting algorithm time complexity is O ($ NlogN $), there can be no smaller than it is algorithms

But there are still some limitations merge algorithm

  1. Space complexity is not optimal
  2. In practice, not necessarily encounter the worst case
  3. In addition to other actions comparison algorithms (eg access) is also very important
  4. Some also can not compare the array sorting

Quick Sort

Quick sort requires little space and time complexity satisfy O ($ logN $), but in some cases the rate will be reduced to O ($ N ^ 2 $).

The basic algorithm

Quick sort is a divide and conquer algorithm, an array is divided into two parts, the two parts then sorted separately. When the two sub-arrays, orderly and ordered a whole array naturally.

In the merging algorithm, the array is equally divided into two parts, the recursive processing before the entire array. In the quick sort, the slicing position in the array depends on the contents of the array, recursion occurs after processing the entire array.

Implementation code

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)

Usually slicing algorithm to select a [lo] As slice elements. Define two pointers, a left to right, a right to left, the left pointer when it encounters an element of greater than or equal, less a right pointer encountered its elements, exchanged. When the two meet pointer, returns an array of the greatest left to the right number.

If you can not understand the words, you can write several array simulate this process.

Code:

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

Place sliced

If you create a secondary array to be segmented, copy back the cost may outweigh the benefits.

Do not cross-border

Carefully throw pointer array bounds

Maintaining randomness

At first upset in favor of quick-sort an array

Terminator Cycle

Elements such as segmentation and the same value may occur, consider

Segmentation processing element has a duplication of

The above method may appear equivalent exchange, but avoid the time complexity is reduced to the square of the level

Termination of recursive

Rational use of segmentation elements, to ensure that the segmentation elements are placed in the correct position

Algorithm Improvement

Insertion sort to the switching

When a small number of columns, you can use the quick sort
will be if(hi<=lo)returnrevised toif(hi<=lo+M){Insertion.sort(a,lo,hi);return}

Three sampling segmentation

Use of the median part of the sub array elements as may be better segmentation results, but requires the loss of the median computation time. General found that the sample size is 3 better effect.

The best sort of entropy

Some elements of the array contains a lot of repetition, but they will still have to sort quick sort can be appropriately modified.

For example three array segmentation is divided into greater than, equal to, less than the portion of slice elements.
Interested can search for detailed tutorial on their own, just to attach java code

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);
    }
}

Some other content on the priority sequence, it can not be considered completely sorted, and even more after it.

Guess you like

Origin www.cnblogs.com/endevelop-gw/p/12508038.html