java冒泡排序-java选择排序-java插入排序-java快速排序

5 篇文章 0 订阅

四种常用排序算法分析

代码及测试性能

**排序代码与测试代码**
public class SortUtil {

    /**
         * 冒泡排序 稳定排序 
         *  @param data数据源
         */
    public static void bubbleSort(int data[]) {

        for (int i = 0; i < data.length-1; i++) {

            for (int j = 0; j < data.length - 1 - i; j++) {

                if (data[j] > data[j + 1]) {
                    // 交换数据
                    int temp = data[j];
                    data[j] = data[j + 1];
                    data[j + 1] = temp;

                    // data[j] = data[j]^data[j+1];
                    // data[j+1]=data[j]^data[j+1];
                    // data[j] = data[j]^data[j+1];

                }
            }
        }
    }

    /**
     * 选择排序,不稳定排序
     * 
     * @param data
     */
    public static void selectSort(int data[]) {
        for (int i = 0; i < data.length; i++) {
            int select = i;
            for (int j = i +1; j < data.length; j++) {
                if (data[select] > data[j]) {
                    select = j;
                }
            }
            if (select != i) {
                // 交换数据
                data[i] = data[i] ^ data[select];
                data[select] = data[i] ^ data[select];
                data[i] = data[i] ^ data[select];
            }
        }
    }

    /**
     * 直接插入排序 属于稳定性排序
     * @param data
     */
    public static void insertSort(int data[]){

        int j ;
        int temp;
        for(int i =1;i<data.length;i++){
            j=i;
            temp= data[i];
            while(j>0&&temp<data[j-1]){
                data[j]=data[j-1];
                j--;
            }
            data[j]=temp;
        }       
    }


    /**
     * 快排,非稳定性排序
     * @param data
     * @param start
     * @param end
     */
    public static void quickSort(int data [],int start,int end){
        if(start>=end){
            return;
        }
        //计算中值
        int mid = start-1;
        int temp =0;
        for(int i=start;i<end;i++){
            if(data[i]<=data[end]){
                mid++;
                 temp = data[i];
                data[i]=data[mid];
                data[mid]=temp;

            }
        }
        //将中间值加入索引位置
        mid ++;
        temp =data[end];
        data[end]=data[mid];
        data[mid]=temp;

        //递归
        quickSort(data,start,mid-1) ;
        quickSort(data,mid+1,end);

    }

}
//测试代码
public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        int num;
        Scanner scan = new Scanner(System.in);
        for(;;){
        num = scan.nextInt();
        if(num ==0){
            break;
        }
        int data[] = new int[num];
        Random random = new Random();
        for (int i = 0; i < num; i++) {
            data[i] = random.nextInt(num);
        }
        int data1[] = Arrays.copyOf(data, num);
        int data2[] = Arrays.copyOf(data,num);
        int data3[]=Arrays.copyOf(data, num);
        printArray(data);
        //测试冒泡
        long currentTime = System.currentTimeMillis();
        SortUtil.bubbleSort(data);
        System.out.println("冒泡排序用时间:"+(System.currentTimeMillis()-currentTime));
        printArray(data);
        //测试选择
        currentTime = System.currentTimeMillis();
        SortUtil.selectSort(data1);
        System.out.println("選擇排序用时间:"+(System.currentTimeMillis()-currentTime));
        printArray(data1);
        //测试插入
        currentTime = System.currentTimeMillis();
        SortUtil.insertSort(data2);
        System.out.println("插入排序用时间:"+(System.currentTimeMillis()-currentTime));
        printArray(data2);
        //测试快排
        currentTime = System.currentTimeMillis();
        SortUtil.quickSort(data3,0,num-1);
        System.out.println("快速排序用时间:"+(System.currentTimeMillis()-currentTime));
        printArray(data3);
        }

    }

    /**
     * 打印数组
     * @param data
     */
    public static void printArray(int data[]){
        for(int i =0;i<data.length;i++){
            System.out.print("\t"+data[i]);
        }
        System.out.println();

    }

}
**排序性能结果**
设备:笔记本 处理器i5(主频2.3) 内存8g
测试结果单位: 毫秒
数量冒泡选择插入快排
10000000
1000013037300
10000014949319310398
2000006009911280420314
500000。。。706907065771
1000000。。。282700107803103
10000000。。。。。。。。。1246
100000000。。。。。。。。。14216

算法实现思路及复杂度分析

冒泡排序
算法思想:外部进行n次大循环,每次大循环,里面嵌套一个小循环;小循环通过遍历相邻位置比较大小交换位置,最终将最大值移动到最后一个位置(升序),然后将剩余的数据再进行遍历,得到一个最大值后,小循环范围减一,有大循环控制,再经过小循环遍历得到剩余数据的最大值,并通过相邻互换移动到,剩余数据的最后一个位置,以此类推最后得到一个有序序列。通过相邻位置互相比较交换,不会改变相等数据原来的相对位置,为稳定排序。
此排序内循环,类似于小鱼在水滴吐泡泡一样,气泡随着上升,越来越大,故称冒泡排序。
算法复杂度分析:
最优情况:外循环,(n-1);内循环平均, n/2 时间复杂度:n*(n-1)/2 ==> n^2
最差情况:外循环,(n-1);内循环平均,(n/2)3 时间复杂度:n*3(n-1)/2==>n^2

选择排序
算法思想:外部进行n次大循环,内部嵌套一个小循环;小循环通过遍历记录最小或最大位置,然后最后进行一次交换,得到最小值或最大值。此排序算法和冒泡排序优点在于,优化了交换次数。缺点由于只是记录位置,并最后做一次交换,会造成相等数据,原始顺序会改变,为不稳定排序算法。
算法复杂度:外循环,(n);内循环平均,n-1/2 时间复杂度:n*(n-1)/2 ==>n^2;
注意:选择相对冒泡优化了交换次数,但是比较次数是一样的。选择比冒泡略快。

直接插入排序
算法思想:将无序数据看出两个数据集,排序的过程就是将无序的数据,插入到有序数据合适的位置;在插入的过程,会伴随着数据的平移。
算法复杂度:外循环,(n-1);内循环平均:n-1/4 时间复杂度:(n-1)*(n-1)/4==>n^2;

快速排序
算法思想:将无序数据,按照某个值(可以随机选,列如最后一个值)一分为二,小的值在左边,大的值在右边,然后再对左右两个数据做同样的操作,最后得到一个有序的序列。快速排序在划分左右数据的时候会改变相等数据在原来数据中的相对位置,为不稳定排序算法。
算法复杂度:最坏情况:n*(n-1)/2==>n^2;平均复杂度:n*logn
空间复杂度:最优情况:n 最坏情况 n*logn

注意:在交换数据时候,通过^运算交换的时候,一定要保证不是在一个数据上操作。本人在排序的时候,用^运算的时候,没有考虑到是同一个操作地址的情况,结果出现排序后出现大量的零值。

列如 :
int a,b; a=1,b=1;
data[a]=data[a]^data[b];
data[b]=data[a]^data[b];
data[a]=data[a]^data[b];
这样运算后的结果 data[1]=0;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值