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

介绍三种时间复杂度为 N^2的三种排序及实现:

选择排序:

一堆扑克牌摊开,

第一次从第二张牌开始之后的每一张牌都与第一张牌比较,假如比第一张牌小,那么就和第一张牌交换,直到比较到最后一张牌,那么本次就产生了最小的一张牌,且这张牌就是放在第一位的那张。也就是说假如数组arr[10],那么第一次从arr[1]开始,和arr[0]比较,小于arr[0]就交换,直到arr[9]。一轮下来就确定了arr[0]是最小的,下一轮就从arr[2]开始,和arr[1]比较,又可以确定arr[1]是第二小的。。。。

代码实现如下:

void select_sort(int *arr){

    for(int i = 0; i < arrsize; i++){
        for(int j = i+1; j < arrsize; j++){
            if(arr[j] < arr[i]) swap(arr,j,i);
        }
    }
}

void swap(int*arr, int i, int j){
    arr[i] = arr[i] ^ arr[j];
    arr[j] = arr[i] ^ arr[j];
    arr[i] = arr[i] ^ arr[j];
}

因为每次选一个最小的都得遍历一次数组,所以时间复杂度为N^2,其实仔细想一下,选择排序过程会出现重复比较两个树的情况,所以造成了不必要的浪费。就比如说 一个数组就3个数 5 6 3,现在被比较的数是5,而6比他大,不会交换。 下一个数是3 那么就会交换,导致原本 5 6 3 变成了3 6 5。然后又要用5和6比较,变成3 5 6;而实际上5和6已经比较过,这里就多了一次比较。

冒泡排序:

同样一堆扑克牌,盖着没有摊开。

翻开第一张扑克牌,放到arr[0]位置,再翻开第二张扑克牌,和第一张比较,把小的那张放到一个空的新牌堆(这里只是便于理解,实际上不需要额外的空间,用原来的数组就行),再从原牌堆翻开一张和大的比较,同样,谁小谁放到新牌堆。这样下来,原牌堆拿完,你手里的就是最大的那张牌。 然后从新牌堆继续这个过程找出第二大的。。。

void maopao_sort(int *arr){

    for(int j = arrsize - 1; j > 0; j--)
    {
        for(int i = 0; i < j; i++){
            if( arr[i+1] < arr[i]) swap(arr,i+1,i);
        }
    }
}

同样,冒泡排序也是要遍历整个牌堆,而且要遍历N次,一次只能找出一个最大值,所以也是时间复杂度为N^2的算法,在比较过程中同样出现重复比较的情况。比如本来就是顺序的3个数,3 5 6,

那么

3和5比较,不用交换;

5和6比较,不用交换;

确定6最大;

3和5比较,确定5;

最后确定顺序3 5 6;

所以在这个过程中3和5其实是比较了两次,重复了。

插入排序:

一堆扑克牌,

拿第一张,那么到手里因为只有一张,所以是有序的,然后拿第二张,比较第二张和第一张的大小,

如果 第二张>第一张 那么插在第一张的后面,否则插在第一张的前面,至此手上的两张牌也有序,

拿第三张,和你手上最大的那张牌比较,直到找到合适的位置插入,循环直到把牌拿完,手上的牌自然就有序了。

void insert_sort(int *arr){

    for(int i = 1; i < arrsize; i++){
        for(int j = i - 1; j >= 0; j--)
        {
            if(arr[j+1] < arr[j]) {
                swap(arr,j+1,j);
            }else {
                break;
            }
        }
    }
}

插入排序和选择排序以及冒泡排序不同的是,它的比较是不重复的,因为之前比较过的已经在手上形成了一个有序的牌型,每次拿一个新牌去比较都只是比较有序排序最大的,直到找到自己合适的位置。所以插入排序相对于上面两种排序要更好一些,那么为什么插入排序的时间复杂度依然是N^2呢,是因为有最差的情况比如 9 8 7 6 这四个数。

第一次拿出来9,第二次拿出来8需要和9比较,形成8 9;

第三次拿出来7,需要和9比较,需要和8比较,形成7 8 9;

第四次拿出来6,需要和9比较,需要和8比较,需要和7比较,形成6 7 8 9;

会发现如果是一个从大到小排好序的数组,用上述插入排序算法,需要比较的次数也是等差数列,自然也是N^2级别的。

下一篇文章再讲述归并排序,快排等时间复杂度N*LOGN的排序算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值