• 排序算法


    几种排序算法的比较

    直接插入排序

    算法

    插入排序由N-1趟排序组成。对于p=1到N-1趟,插入排序保证从位置0到位置p上的元素为已排序状态。

    时间复杂度

    最差的情况下,第p次排序,需要的比较次数是p次,则总的比较次数为1+2+3+……+N-1=O(N^2)。

    平均情况,O(N^2)

    最好情况,O(N)

    空间复杂度

    每次比较都是两个元素的交换,所以空间复杂度为O(1)

    代码示例

    package sort;
    
    import java.util.Random;
    
    /**
     * Created by wuchao on 17-3-28.
     */
    public class Insert {
        public static void main(String[] args){
            int[] array = getData(100);
            printArray(insertSort(array));
        }
    
        //插入排序
        public static int[] insertSort(int[] array){
            int N = array.length;
            int j;
            for(int i=1 ; i<N ; i++){
                //array[0,(i-1)]是已经排序的,现在判断array[i]插在哪
                int tmp = array[i];
                for(j=i;j>0&&array[j-1]<tmp;j--){
                    array[j]=array[j-1];
                }
                array[j]=tmp;
            }
            return array;
        }
    
    
    
        //返回一个长度为N的随机数组,元素大小[0,N]
        public static int[]  getData(int N){
            int[] array = new int[N];
            if(N<=0) return array;
            Random random = new Random();
            for(int i=0;i<N;i++){
                array[i]= random.nextInt(N);
            }
            return array;
        }
        //打印数组
        public static void printArray(int[] array){
            System.out.print("[");
            for(int i=0;i<array.length;i++){
                System.out.print(array[i]+",");
            }
            System.out.print("]");
            System.out.println();
        }
    }
    

    Shell排序

    算法

    基于插入排序,但它通过比较相邻一定间隔的元素来工作。各趟比较所用的距离随着算法进行而减少,直到只比较相邻元素(间隔为1)的最后一趟为止。

    时间复杂度

    最差情况,O(N^2)

    平均情况,O(N^1.3)

    最好情况,O(N)

    空间复杂度

    每次比较都是两个元素的交换,所以空间复杂度为O(1)

    代码示例

    package sort;
    
    import java.util.Random;
    
    /**
     * Created by wuchao on 17-3-28.
     */
    public class Shell {
        public static void main(String[] args){
            int[] array = getData(100);
            printArray(array);
            printArray(shellSort(array));
        }
    
        //shell排序
        public static int[] shellSort(int[] array){
            int N = array.length;
            int j;
            //比较间隔gap由N/2逐步递减为1
            for(int gap = N/2;gap>0;gap/=2){
                for(int i=gap;i<N;i++){
                    int tmp = array[i];
                    for(j=i;j>=gap&&array[j-gap]>tmp;j -=gap){
                        array[j]=array[j-gap];
                    }
                    array[j]=tmp;
                }
            }
            return array;
        }
    
    
    
        //返回一个长度为N的随机数组,元素大小[0,N]
        public static int[]  getData(int N){
            int[] array = new int[N];
            if(N<=0) return array;
            Random random = new Random();
            for(int i=0;i<N;i++){
                array[i]= random.nextInt(N);
            }
            return array;
        }
        //打印数组
        public static void printArray(int[] array){
            System.out.print("[");
            for(int i=0;i<array.length;i++){
                System.out.print(array[i]+",");
            }
            System.out.print("]");
            System.out.println();
        }
    }
    

     快速排序

    算法

    在数组中选取一个元素,比如选第一个元素,经过一定的方法,使得数组重排,结果为比该元素小的元素都在该元素的左侧,比该元素大的元素都在该元素的右侧。

    重排方法如下:

      数组为array=[5 2 7 3 9 4 0 1]

      (1)选取第一个元素为基x=5,相当于在array[i=0]处挖了一个坑,元素被取走了。

      (2)建立索引i=0,j=6(i指向数组头部,j指向数组尾部),此时i=0指向数组的那个坑

      (3)从尾部开始查找第一个小于x的值(查找范围为(i,j] ),然后令j指向该元素,并将该元素赋值数组的那个坑并i++(i指向的那个坑),此时j指向数组的新的坑

      (4)从头部开始查找第一个大于x的值(查找范围[i,j) ),然后令i指向该元素,并将该元素复制给数组的那个坑并j--(j指向的坑),此时i指向数组新的坑

      (5)直到i<j不成立时有i=j,这时坑的位置是i或j,用基x填这个坑,array[i]=x;

    数组[5 2 7 3 9 4 0 1]排序细节如下

    [ _ 2 7 3 9 4 0 1 ]   x=5  i=0,j=7

    [ 1 2 7 3 9 4 0 _ ]   x=5  i=0,j=7

    [ 1 2 _ 3 9 4 0 7 ]   x=5  i=2,j=7

    [ 1 2 0 3 9 4 _ 7 ]   x=5  i=2,j=6

    [ 1 2 0 3 _ 4 9 7 ]   x=5  i=4,j=6

    [ 1 2 0 3 4 _ 9 7 ]   x=5  i=4,j=5

    [ 1 2 0 3 4 5 9 7 ]   x=5  i=5,j=5

    时间复杂度

      最差情况:O(n^2)

      平均情况:O(nlogn)

    空间复杂度

      O(nlogn)

    代码

    代码如下

    /**
     * Created by wuchao on 17-3-29.
     */
    import java.util.*;
    public class test {
        public static int array[] = {5,2,7,1,2,9,3};
        public static void main(String[] args) {
    
            quickSort(array,0,6);
            System.out.println(Arrays.toString(array));
        }
        public static void quickSort(int[] array,int l,int r){
            if(l<r){
                int i=l,j=r;
                int value = array[l];
                while(i<j){
                    while(i<j && array[j]>value){
                        j--;
                    }
                    if(i<j){
                        array[i]=array[j];
                        i++;
                    }
                    while(i<j&&array[i]<value){
                        i++;
                    }
                    if(i<j){
                        array[j]=array[i];
                        j--;
                    }
                }
                array[i]=value;
                quickSort(array,l,i-1);
                quickSort(array,i+1,r);
            }
        }
    }
    

    归并排序

    算法

    这个算法的基本操作是合并两个已排序的表。在这里合并函数的几个参数a,tmpArray,leftPos,rightPos,rightEnd分别表示待排序数组、临时数组、左边起点、右边起点、右边终点。

    时间复杂度

    最差和最好情况下都是O(nlogn)

    空间复杂度

    O(1)

    代码

    import java.util.Arrays;
    
    /**
     * 归并排序
     */
    public class Merge {
        public static void main(String[] args){
            int[] array={2,7,3,77,3,56,3,74,2,5,12,74,34,75};
            mergeSort(array);
            System.out.println(Arrays.toString(array));
        }
        //排序算法入口
        public static void mergeSort(int[] a){
            int[] tmpArray = new int[a.length];
            mergeSort(a,tmpArray,0,a.length-1);
        }
        //分治并合并
        private static void mergeSort(int[] a,int[] tmpArray,int left,int right){
            if(left<right){
                int middle = (left+right)/2;
                mergeSort(a,tmpArray,left,middle);
                mergeSort(a,tmpArray,middle+1,right);
                merge(a,tmpArray,left,middle+1,right);
            }
        }
        //合并
        //此时数组a的[leftPos]-[rightPos-1]和[rightPos]-[rightEnd]已经是两个排序的子数组
        //下面函数负责将这两个部分合并,并放入放到tmpArray数组的[leftPos]-[rightEnd]位置
        //最后将tmpArray对应部分拷贝回原来数组
        private static void merge(int[] a,int[] tmpArray,int leftPos,int rightPos,int rightEnd){
            int leftEnd = rightPos-1;
            int tmpPos = leftPos;
            int numElements = rightEnd-leftPos+1;
    
            while(leftPos<=leftEnd && rightPos<=rightEnd){
                if(a[leftPos]<=a[rightPos]){
                    tmpArray[tmpPos++]=a[leftPos++];
                }else{
                    tmpArray[tmpPos++]=a[rightPos++];
                }
            }
            while(leftPos<=leftEnd){
                tmpArray[tmpPos++]=a[leftPos++];
            }
            while(rightPos<=rightEnd){
                tmpArray[tmpPos++]=a[rightPos++];
            }
            for(int i=0;i<numElements;i++,rightEnd--){
                a[rightEnd]=tmpArray[rightEnd];
            }
        }
    }
    
  • 相关阅读:
    IIS是如何处理ASP.NET请求的
    c# Socket通讯中关于粘包,半包的处理,加分割符
    windows2008(64位)下iis7.5中的url伪静态化重写(urlrewrite)
    C#微信公众号/订阅号开发 接口源码
    C#线程池多线程Socket通讯 服务器端和客户端示例
    百度地图JS调用示例
    c# 图片转二进制/字符串 二进制/字符串反转成图片
    电商项目面试总结
    96. Unique Binary Search Trees
    92.Reverse Linked List II
  • 原文地址:https://www.cnblogs.com/wuchaodzxx/p/6632365.html
Copyright © 2020-2023  润新知