算法大全(一)|冒泡排序,插入排序,选择排序

1.如何分析一个排序算法

1.排序算法的执行效率
1)最好情况,最坏情况,平均情况时间复杂度
2)时间复杂度的系数,常数和阶数
3)比较次数和交换次数

2.排序算法的内存消耗
内存消耗可以引入空间复杂度来衡量,原地排序算法,特指空间复杂度为O(1)的算法

3.排序算法的稳定性
稳定性是指,如果待排序的序列中有相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。

2. 冒泡排序,插入排序 ,选择排序

1.冒泡排序
private static void test2(int[] arrs) {
    if(arrs.length<2){
        return;
    }
    for(int i=0;i<arrs.length-1;i++){
        boolean flag=true;//用来判断如果之间有一次没有进行位置互换,那么说明顺序已经排好没有必要再走之后的排序了
        for (int j=i+1;j<arrs.length;j++){
            if(arrs[i]>arrs[j]){
                arrs[i]=arrs[i]^arrs[j];//做变量切换
                arrs[j]=arrs[j]^arrs[i];
                arrs[i]=arrs[i]^arrs[j];
                flag=false;
            }
        }
        if (flag){
            break;
        }
    }
}
分析:
 1.冒泡排序是原地排序算法吗?
   是原地排序算法,他的排序过程中,可以不引入其他的变量,就算上boolean flag变量,他也是个空间复杂度为O(1)的算法
 2.冒泡排序是稳定的排序算法吗?
   是稳定的排序算法,因为当相邻的两个元素是相同的时候,我们不调换位置,所以冒泡是稳定的
 3.冒泡排序的时间复杂度是多少?
   最好情况下,本来就是有序的,我们只需要排序一次就可以了,所以最好复杂度是O(n)
   最坏情况下,完全倒序的,我们需要排序N次,所以最坏复杂度是O(n^2) 
   平均情况下,如何计算呢?
     用有序度和逆序度来描述。
     有序度时数组中具有有序关系的元素的大小。比如[2,4,3,1,5,6] 有序度是11
      而我们称[1,2,3,4,5,6]这种数组,它们的有序度是n(n-1)/2,是满有序
     而一个数组从初始刀满有序,需要进行交换,交换一次有序度就加一。
        所以交换次数=满有序-有序度 
      可以看出最差的情况就是有序度是0,然后到满有序需要交换n(n-1)/2次,而最好的情况是满有序一次都不交换。
       所以我们取它们的中间 n(n-1)/2/2 =n(n-1)/4 也就是约等于n^2,所以平均时间复杂度就是n^2 
2.插入排序
//插入排序(插入排序主要分为两个区域,第一是有序的区域,第二是无序的区域,拿着无序区域中的第一个跟所有有序区的区比,如果
//  无序区域的第一个值小于有序区的值,那就将有序区的值向后移动一位,再比较,直到数组到0或者有序区的数据小于无序区的数据,
//  break 最后将无序区的第一个值插入到最新的位置。)
public static void test3(int[] arrs){
    if(arrs.length==1){
        return;
    }
    for (int i=1;i<arrs.length;i++){
         int value=arrs[i];//记录无序区的第一个元素,从下标1开始,默认下标0就是有序区
        int j=i-1;
        for (;j>=0;j--){
            if (arrs[j]>value){//判断是否小于有序区的值,小于就换位置
                arrs[j+1]=arrs[j];
            }else{break;}
        }
        arrs[j+1]=value;//将无序区的数据赋值过去
    }
}

分析:1.插入排序是不是原地排序呢?
       是原地排序       
     2.插入排序是稳定的排序算法么?
       是稳定的排序算法,如果相邻的俩个值相等,那么是不会调换位置的
     3.插入排序的时间复杂度是多少?
        最好时间复杂度是n
        最坏时间复杂度是n
        而它的平均时间复杂度计算,我们可以考虑一下,在数组中插入一个值的话,他的时间复杂度是n,因为要移动n次
          那插入n个值,他的时间复杂度当然就是n^2了。
3.选择排序
//选择排序,分为有序区和无序区,从无序区中选择一个最小的放到有序区的末尾。
public static void test4(int[] arrs){
    System.out.println(Arrays.toString(arrs));
    if(arrs.length==1){
        return;
    }
    for(int i=0;i<arrs.length;i++){
        int low=i;//i代表的是无序区的第一个元素,初始以这个元素为最小值
        for(int j=i;j<arrs.length;j++){
            if(arrs[j]<arrs[low]){//如果索引j的值比最小值还小,那么记录当前索引为最小值索引
                low=j;
            }
        }
        if(low!=i){//如果最小值索引不是无序区的第一个值,那么说明中间出现了赋值操作,需要进行最小值交换操作
            int tmp=arrs[i];
            arrs[i]=arrs[low];
            arrs[low]=tmp;
        }
    }
    System.out.println(Arrays.toString(arrs));
}

分析:1.选择排序是不是原地排序呢?
       是原地排序,并没有新增空间,空间复杂度是O(1)       
     2.选择排序是稳定的排序算法么?
       不是稳定的排序算法,因为会存在交换的可能
       比如[2,4,4,3,1] ,最小值是3,会和第一个4换位置,这时候第一个4到了第二个4的后面,所以不是稳定排序
     3.选择排序的时间复杂度是多少?
        最好时间复杂度是n
        最坏时间复杂度是n
        而它的平均时间复杂度计算,是n^2,他的时间复杂度当然就是n^2了。
4.为什么插入排序要比冒泡排序好一些?
1.插入排序和冒泡排序的时间复杂度都是n^2,而且都是稳定算法,而且都是原地排序,那为什么插入排序要好一些呢?
  可以仔细的观察,冒泡排序的话,它比较完了元素之后进行交换的时候,至少需要3步才能实现
    int tmp=a;
    a=b;
    b=tmp;
  而插入排序的话,只需要移动一次即可
    a[j+1]=a[j];
  所以可以看出来,比如一次赋值操作需要耗费m的时间,冒泡排序耗费3m的时间,而插入排序耗费k的时间,这样来看,那就是插入时间要少一些。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值