排序算法之冒泡排序

冒泡排序

今天学习一下冒泡排序,它是最简单的一种排序算法。这里我们按照降序排列

原理
  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

  • 针对所有的元素重复以上的步骤,除了最后一个。

  • 持续每次对越来越少的元素重复上面的步骤,知道没有任何一对数字需要比较。

首先,里面用到的swap函数定义如下:

//交换位置
void swap(int a[],int i,int j)
{
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;
}

1.第一种:

void maopaoSort1(int a[],int aLength)
{
    int i,j;
    for (i=0; i<aLength; i++) {
        for (j=0; j<aLength-1; j++) {
            if (a[j]<a[j+1]) {
                swap(a, j, j+1);
            }
        }
    }

这种排序算法是正宗的冒泡排序,原理如下:

  • 总共比较aLength-1轮,第一轮是用相邻的两个元素比较,如果第一个元素<第二个元素,就交换。然后再次比较。
  • 直到比较完aLengh-1轮。
  • 排序结束。
    原理图:

55cc95ef62094.png

3.第二种:

void maopaoSort2(int a[],int aLength)
{
    int i,j;
    int flag = 1;   //falg tag
    for (i=0; i<aLength && flag==1; i++) {
        flag = 0;
        for (j=0; j<aLength-1; j++) {
            printf("aj----aj+1:%d----%d   \n",a[j],a[j+1]);
            if (a[j]<a[j+1]) {
                swap(a, j, j+1);
                flag = 1;
            }
        }
    }
}
 

这种排序变形就是再第二种的基础上添加了一个tag标志。这样做的目的就是由于如果一个待排序序列是这样的:
{2,1,3,4,5,6,7,8,9};
这样的排序 其实只需要将1,2交换就是有序的了,所以用第二种或者第一种方法进行排序很多就是没有必要的。也就是,2,3,4下面的都没有必要再次去比较了。
如果tag==1,说明了需要交换,但是如果tag为0,说明了后面的就没有必要再次排序了。因此可以大大的减少排序时间(当然只是针对大概有序的序列,效果会比较明显。)

原理图:

EE0EB7B1-9316-4A0F-A3DB-47340A7B05A9.png

这三种排序方式都是冒泡排序。他们的时间复杂度都是:O(n^2);

测试main函数如下:

int main(int argc, const char * argv[]) {

    int a[] = {12,34,9,1,5,8,3,7,4,6,2,43,42,16,23};
    maopaoSort1(a,15);
    printf("\n");
 //   maopaoSort2(a,15);
  //  printf("\n");
}

不要一次同时执行两个排序算法,这样的话第二次执行的排序算法的数组就是第一次排序过的数组了。
至此,冒泡排序就告一段了,希望大家能够从中学到一些东西。

转载于:https://www.cnblogs.com/zhanggui/p/4728503.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值