12种排序方法的算法

1.插入排序

/*插入排序
最好复杂度:O(n)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性       :稳定
补充           :STL的sort算法和stdlib的qsort算法中,
                     都将插入排序作为快速排序的补充,用于少量元素的排序,通常为8个一下。
*/
public class InsertionSort {
    public static void insertionSort(int[] array,int first,int last) 
    {
        int temp;
        for (int i=first+1;i<=last;i++) 
        {
            temp=array[i];
            int j=i-1;
            while((j>=first) && array[j]>temp) 
            {
                array[j+1]=array[j];
                j--;
            }
            array[j+1]=temp;
        }
    } 
}

2.希尔排序

/*希尔排序
最好复杂度:O(n)
最坏复杂度:O(nlogn)
平均复杂度:..
空间复杂度:O(1)
稳定性       :稳定
补充           :就是直接插入排序的dx大小分类。
*/
public class ShellSort {
    public static void shellSort(int[] arrays,int first,int end) 
    {
        int temp;
        int gap=0;//跳跃间隔
        int length=end-first+1;
        int j=0;
        while(gap<=length) 
        {
            gap=gap*3+1;
        }
        while(gap>0) 
        {
            for(int i=first+gap;i<=end;i++) 
            {
                j=i-gap;
                temp=arrays[i];
                while((j>=0) && (arrays[j]>temp)) 
                {
                    arrays[j+gap]=arrays[j];
                    j=j-gap;
                }
                arrays[j+gap]=temp;
            }
            gap=(gap-1)/3;
        }
    }
}

3.二分查找插入排序

/*二分插入排序
最好复杂度:O(nlogn)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性       :稳定
补充           :当n比较大时,总排序码的比较次数比直接插入排序的最差情况好得多,但比最好情况要差。
*/
public class BinaruInsertSort {
    public static void binaryInsertSort(int[] arrays,int first,int last) 
    {
        int temp,left,right,middle;
        for (int i=first+1;i<=last;i++) 
        {
            temp=arrays[i];
            left=first;
            right=i-1;
            while(left<=right) 
            {
                middle=(left+right)/2;
                if (arrays[middle]>temp) right=middle-1;
                else left =middle+1;

            }
            for (int j=i-1;j>=left;j--) arrays[j+1]=arrays[j];
            arrays[left]=temp;
        }
    }
}

4.冒泡排序

/*冒泡排序
最好复杂度:O(n)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性       :稳定
补充           :冒泡排序最坏的情况下,需要进行O(n^2)次交换,而插入排序只要最多O(n)的交换。
                     比插入排序差很多
                     在第一次内部循环实行时,使用旗标来表示是否需要交换的可能,也有可能那最好的时间复杂度到O(n)
                    对于比较的效果减少。
                    下面的程序已经加了标志位mark;
*/
public class BubbleSort {
    public static void bubbleSort(int[] arrays,int first,int last) 
    {
         int i=last;
         int temp;
         boolean mark=true;
         while(i>first && mark) 
         {
             mark=false;
             for (int j=first;j<=i-1;j++) 
                 if (arrays[j]>arrays[j+1]) 
                 {
                     temp=arrays[j];
                     arrays[j]=arrays[j+1];
                     arrays[j+1]=temp;
                     mark=true;
                 }
             i--;
         }
    }
}

5.鸡尾酒排序

/*鸡尾酒排序/双向冒泡排序
最好复杂度:O(n)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性       :稳定
补充           :其实就是双向的冒泡排序,同样
*/
public class CocktailSort {
    public static void cocktailSort(int[] arrays,int first,int end) 
    {
        int temp;
        while(first<end) 
        {
            for (int j=end;j>first;j--)
                if (arrays[j]<arrays[j-1])
                {
                    temp=arrays[j];
                    arrays[j]=arrays[j-1];
                    arrays[j-1]=temp;
                }
            first++;
            for (int j=first;j<end;j++) 
                if (arrays[j]>arrays[j+1]) 
                {
                    temp=arrays[j];
                    arrays[j]=arrays[j+1];
                    arrays[j+1]=temp;
                }
            end--;
        }
    }
}

6.选择排序

/*选择排序
最好复杂度:O(n^2)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性       :不稳定
补充           :最好情况,已经有序,交换0次,最坏情况,交换n-1次,
                     比较次数n(n-1)/2;判断比交换速度快,所以选择排序比冒泡排序快
*/

public class SelectionSort {
    public static void selectionSort(int[] arrays,int first,int last) 
    {
        int min;
        int temp;
        for (int i=first;i<=last-1;i++) 
        {
            min=i;
            for (int j=i+1;j<=last;j++) 
                if (arrays[min]>arrays[j]) min=i;
            if (min!=i) 
            {
                temp=arrays[min];
                arrays[min]=arrays[i];
                arrays[i]=temp;
            }
        }
    }
}

7.快速排序

/*快速排序
最好复杂度:O(nlogn)
最坏复杂度:O(n^2)
平均复杂度:O(nlogn)
空间复杂度:O(log2n)
稳定性       :不稳定
补充           :虽然是nlogn但是理论上最快
                     本程序选用第一个作为基准,如果需要别的数如随机数做基准只需要
       pivot与arrays[first]交换
       Partiton切割函数
*/
public class QuickSort {
    public static void quickSort(int[] arrays,int first,int end) 
    {
        int i,j;
        int pivot=arrays[first];
        if(first<end) 
        {
            i=first;
            j=end;
            do 
            {
                while (arrays[j]>pivot && i<j) 
                   j--; 
                if (i<j) 
                {
                    arrays[i]=arrays[j];
                    i++;
                }
                while (arrays[i]<pivot && i<j)
                    i++;
                if(i<j) 
                {
                    arrays[j]=arrays[i];
                    j--;
                }
            } while(i!=j);
            arrays[i]=pivot;
            quickSort(arrays,first,i-1);
            quickSort(arrays,i+1,end);

        }
    }
}

8.分治排序

/*分治排序
最好复杂度:O(nlogn)
最坏复杂度:O(nlogn)
平均复杂度:O(nlogn)
空间复杂度:O(n)
稳定性       :稳定
补充           :内存上需要线性,对于大量数据一次性内存读不完的数据不行。
*/
public class SortingOrder {
    private static void mergeArrays(int[] arrays,int first,int mid,int end) 
    {
        int i=first;
        int j=mid+1;
        int k=0;
        int[] temp=new int[end-first+1];
        while(i<=mid && j<=end) 
        {
            if (arrays[i]<=arrays[j]) temp[k++]=arrays[i++];
            else temp[k++]=arrays[j++];
        }
        while (i<=mid) temp[k++]=arrays[i++];
        while (j<=end) temp[k++]=arrays[j++];
        System.arraycopy(arrays,first, temp,0, end-first+1);
    }


    public static void mergeSort(int[] arrays,int first,int end)
    {
        if (first<end) 
        {
            int mid=(first+end)/2;
            mergeSort(arrays,first,mid);
            mergeSort(arrays,mid+1,end);
            mergeArrays(arrays,first,mid,end);          
        }
    }
}

9.堆排序

/*堆排序
最好复杂度:O(nlogn)
最坏复杂度:O(nlogn)
平均复杂度:O(nlogn)
空间复杂度:O(1)
稳定性       :不稳定
补充           :做一次堆调整的时间复杂度为O(logn)
                     用来维护一个K大的数列的最好选择
        JAVA中PriorityQueue的底层实现。
        floor() 向下取整
                      大顶堆维护
*/
public class HeapSort {
    private static int getParent(int i) 
    {
        return (int) Math.floor((i-1)/2);
    }

    private static int getLeftChildren(int i) 
    {
        return 2*i+1;
    }

    private static int getRightChildren(int i) 
    {
        return 2*i+2;
    }

    private static void heapAdjust(int[] arrays,int i,int size) 
    {
        int l=getLeftChildren(i);
        int r=getRightChildren(i);
        int largest;
        int temp;
        if(l<size && arrays[l]>arrays[i]) largest=l;
        else largest=i;
        if(r<size && arrays[r]>arrays[largest]) largest=r;
        if (largest!=i) 
        {
            temp=arrays[i];
            arrays[i]=arrays[largest];
            arrays[largest]=temp;
        }
        heapAdjust(arrays,largest,size);
    }

    private static void buildHeap(int[] arrays,int size) 
    {
        for (int i=size/2;i>=0;i--)  heapAdjust(arrays,i,size);
    }

    public static void heapSort(int[] arrays,int size) 
    {
        buildHeap(arrays,size);
        int temp;
        for(int i=size-1;i>=0;i--) 
        {
            temp=arrays[0];
            arrays[0]=arrays[i];
            arrays[i]=temp;
            heapAdjust(arrays,0,i);
        }
    }
}

10.桶排序

/*桶排序
最好复杂度:O(n)
最坏复杂度:O(n)
平均复杂度:O(n)
空间复杂度:O(n)
稳定性       :稳定
补充           :桶内使用插入排序,那么桶排序的平均时间复杂度为线性
                    最快
                    但是非常耗空间
                    对于数据密集型非常好用且不大的情况
*/
public class BucketSort {
    public static void bucketSort(int[] arrays,int max) 
    {
        int[] bucket=new int[max+1];
        for (int i=0;i<arrays.length;i++)
            bucket[arrays[i]]=arrays[i];
        int i=0;
        int j=0;
        while(i<arrays.length && j<=max) 
        {
              if(bucket[j]!=0) arrays[i++]=bucket[j];
              j++;
        }
    }
}

11.计数排序

/*计数排序
最好复杂度:O(n+k)   n个数从  0-k的范围  类似于桶排序
最坏复杂度:O(n+k)
平均复杂度:O(n+k)
空间复杂度:O(n)
稳定性       :稳定
补充           :只能对整数进行排序,
                     其次需要数据量小。
*/
public class CountingSort {
    public static void countingSort(int[] arrays,int max) 
    {
        int[] counting=new int[max+1];
        for (int i=0;i<arrays.length;i++) counting[arrays[i]]++;
        int k=0;
        for (int i=0;i<=max;i++) 
            while (counting[i]!=0) arrays[k++]=i;
    }

}

12.基数排序

/*基数排序
最好复杂度:O(n*k) n是排序元素个数,k是数字位数。
最坏复杂度:O(n*k)
平均复杂度:O(n*k)
空间复杂度:O(n+r)   r是桶个数
稳定性       :稳定
补充           :按照从小到大的位数以此比较
*/
public class CardinalitySort {
    public static void cardinalitySort(int[] arrays,int k) 
    {

        int length=arrays.length;
        int i=0;
        int index=1;
        int[][] temp =new int[10][length];//桶链
        int[] order=new int[10];//桶长
        while(i<=(k-1)) 
        {
            for(int j=0;j<length;j++) 
            {
                int lsd=(arrays[j]/index)%10;
                temp[lsd][order[lsd]++]=arrays[j];
            }
            int in=0;
            for (int j=0;j<10;j++) 
            {
                if (order[j]!=0) 
                {
                    for (int d=0;d<order[j];d++)
                        arrays[in++]=temp[j][d];
                }
            }
            i++;
            index*=10;
        }
    }
}

总结:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_42166409/article/details/81516090