冒泡排序详解

先来看一下代码,然后再逐行对照解释,这代码是将number[5] = {5, 4, 3, 2, 1}数组里的数由小到大排列

#include <stdio.h>
int main()
{
    int n=5;
    int number[n] = {5, 4, 3, 2, 1};
    int i, j, temp;
    for (j = 0; j < n - 1; j++)  //外循环 (因为j从0开始,所以要减1)
        for (i = 0; i < n - j - 1; i++)  //内循环  (因为i从0开始,所以要减1)
        {
            //比较两个数的大小,如果前面的数大于后面的就交换
            if(a[i] > a[i + 1])
            {
                temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
            }
        }
}

外循环第一轮(j=0)时:
内循环开始前后原数组:5,4,3,2,1
内循环第1轮后(i=0):4,5,3,2,1
内循环第2轮后(i=1):4,3,5,2,1
内循环第3轮后(i=2):4,3,2,5,1
内循环第4轮后(i=3):4,3,2,1,5

外循环第二轮(j=1)时:
内循环开始前后原数组:4,3,2,1,5
内循环第1轮后(i=0):3,4,2,1,5
内循环第2轮后(i=1):3,2,4,1,5
内循环第3轮后(i=2):3,2,1,45
….


可以看出,第一轮外循环后,把数组中最大的数“5”排到最后,整个内循环过程就像气泡一样一层层往上升。第一轮外循环已经把数组中最大的数拍到最后了,就不用理它了,进入第二轮外循环(j=1),此时内循环只需比较前4(即n - j)个数就行了,以此类推,第二轮外循环把“4”升到顶端,第三轮外循环把“3”升到顶端,第四轮外循环把“2”升到顶端。因为有数组5个数,所以n=5,这样基础的冒泡排序算法就算完成了,可以看出,冒泡排序具有代码简洁、容易理解等优点。

但是!
如果数组的初始值是number[5] = {5, 1, 2, 3, 4},用上面说的冒泡排序,只需要一轮外循环,整个数组就能实现由小到大排序,但是代码并不知道已经排序好了,还会继续进行第2、3、4轮外循环,这样一来,冒泡排序效率不高的缺点就显露出来了,当数据量很大时,就会耗费很多无用的时间。那下面就来看看用什么方法解决这个问题:

其实这个问题也很好解决,只需要做一个标记,如果已排序好就做标记,根据标记退出循环。看下面代码:

#include <stdio.h>
int main()
{
    int n=5;
    int number[n] = {5, 4, 3, 2, 1};
    int i, j, temp;
    bool b; //新增一个布尔变量
    for (j = 0; j < n - 1; j++)  //外循环 (因为j从0开始,所以要减1)
        b=false;// 每次先重置为false
        for (i = 0; i < n - j - 1; i++)  //内循环  (因为i从0开始,所以要减1)
        {
            //比较两个数的大小,如果前面的数大于后面的就交换
            if(a[i] > a[i + 1])
            {
                temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
            }
            b=true;//如果还进行过交换设为true
        }
        //如果上一次没有经过交换,则说明已排好序,b=false,退出外循环
        if(!b){
             break;
              }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值