Java实现几种常见排序方法

先来一个概况图


如果原来表有序 或基本有序的话。可以选择插入或冒泡。
如果不确定是否有序 就选择排序、堆排序、归并排序和基数排序
一般来说稳定性算法优于非稳定性算法,
如果n(数量)比较大,建议推排序 或归并。
如果n较小,建议插入,选择或冒泡。
推排序在求最大,小值时较好。
个人理解。



public class Sort01 {
    /**
     * 冒泡排序算法
     * <li>比较相邻的元素。如果第一个比第二个大,就交换他们两个。</li>
     * <li>对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。</li>
     * <li>针对所有的元素重复以上的步骤,除了最后一个。</li>
     * <li>持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。</li>
     * @param a
     */
    public static void maopao(int[] a){
        if(a==null || a.length<=1){
            return;
        }
        int temp;
        for(int i=0;i<a.length-1;i++){
            for (int j=i+1;j<a.length;j++){
                if(a[i]>a[j]){
                    temp=a[i];
                    a[i]=a[j];
                    a[j]=temp;
                }
            }
        }
    }

    /**
     * 选择排序<br/>
     * <li>在未排序序列中找到最小元素,存放到排序序列的起始位置</li>
     * <li>再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。</li>
     * <li>以此类推,直到所有元素均排序完毕。</li>       *
     * @param a
     */
    public static void selectSort(int[] a){
        if(a==null || a.length<=1){
            return;
        }
        for(int i=0;i<a.length;i++){
            int temp=a[i];
            int position=i;
            for(int j=i+1;j<a.length;j++){
                if(a[j]<temp){
                    temp=a[j];
                    position=j;
                }
            }
            a[position]=a[i];
            a[i]=temp;
        }
    }

    /**
     * 插入排序<br/>
     * <ul>
     * <li>从第一个元素开始,该元素可以认为已经被排序</li>
     * <li>取出下一个元素,在已经排序的元素序列中从后向前扫描</li>
     * <li>如果该元素(已排序)大于新元素,将该元素移到下一位置</li>
     * <li>重复步骤3,直到找到已排序的元素小于或者等于新元素的位置</li>
     * <li>将新元素插入到该位置中</li>
     * <li>重复步骤2</li>
     * </ul>
     * @param a
     */
    public static void insertSort(int[] a){
        if(a==null || a.length<=1){
            return;
        }
        for(int i=1;i<a.length;i++){
            int temp=a[i];
            int j=i-1;
            for(;j>=0 && a[j]>temp;j--){
                a[j+1]=a[j];
            }
            a[j+1]=temp;
        }
    }

    /**
     * 快速排序<br/>
     * <ul>
     * <li>从数列中挑出一个元素,称为“基准”</li>
     * <li>重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分割之后,
     * 该基准是它的最后位置。这个称为分割(partition)操作。</li>
     * <li>递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。</li>
     * </ul>
     *
     * @param a
     * @param start
     * @param end
     */
    public static void quickSort(int[] a,int start,int end){
        if(a==null || a.length<=1){
            return;
        }
        if(start<end){
            int base=a[start];
            int temp;
            int x=start;
            int y=end;
            do {
                while (a[x]<base && x<end){
                    x++;
                }
                while (a[y]>base && y>start){
                    y--;
                }
                if(x<=y){
                    temp=a[x];
                    a[x]=a[y];
                    a[y]=temp;
                    x++;
                    y--;
                }
            }while (x<=y);
            if(start<y){
                quickSort(a,start,y);
            }
            if(end>x){
                quickSort(a,x,end);
            }
        }
    }

    /**
     * 归并排序<br/>
     * <ul>
     * <li>申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列</li>
     * <li>设定两个指针,最初位置分别为两个已经排序序列的起始位置</li>
     * <li>比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置</li>
     * <li>重复步骤3直到某一指针达到序列尾</li>
     * <li>将另一序列剩下的所有元素直接复制到合并序列尾</li>
     * </ul>
     *
     * @param a
     */
    public static void mergeSort(int[] a,int start,int end){
        if(a==null || a.length<=1){
            return;
        }
        if(start<end){
            int center=(start+end)/2;
            mergeSort(a, start, center);
            mergeSort(a, center + 1, end);
            merge(a,start,center,end);
        }
    }

    public static void merge(int[] a,int start,int center,int end){
        int tempArr[]=new int[a.length];
        int middle=center+1;
        int thirdLeft=start;
        int temp=start;
        while (start<=center && middle<=end){
            if(a[start]<=a[middle]){
                tempArr[thirdLeft++]=a[start++];
            }else{
                tempArr[thirdLeft++]=a[middle++];
            }
        }
        while (start<=center){
            tempArr[thirdLeft++]=a[start++];
        }
        while (middle<=end){
            tempArr[thirdLeft++]=a[middle++];
        }
        while (temp<=end){
            a[temp]=tempArr[temp++];
        }
    }
    public static void main(String[] args){
        int[] a={10,2,21,1,34,5,8,4,90, 88};
        //Sort01.maopao(a);
        //Sort01.selectSort(a);
        //Sort01.insertSort(a);
        //Sort01.quickSort(a,0,a.length-1);
        Sort01.mergeSort(a,0,a.length-1);
        System.out.println(Arrays.toString(a));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值