排序算法系类-交换之冒泡优化

前言

上一篇博客介绍了冒泡排序:点击打开链接,今天我来说说冒泡的优化。


优化一

冒泡排序的重要思想就是两两比较,然后交换,这样对于一组杂乱无章的小型数组来说是很有效的,但是如果一个数组经过几轮交换已经变的有序了,例如[2,1,3,4,5,6,7]这个数组,经过第一轮,已经变成有序的了,但顽固的冒泡还是要继续进行没有营养的两两比较,从而牺牲了时间。所以对于这种情况,对冒泡排序进行小型整容,便可以减少程序运行时间。

原理

方法就是用一个flag来判断一下,当前数组是否已经有序,如何判断是否有序呢?如果里面一层循环在某次扫描中没有执行交换,则说明此时数组已经全部有序列,无需再扫描了。因此,每次发生交换,就标记,如果某次循环完没有标记,则说明已经完成排序,退出循环,这样可以明显的提高冒泡排序的表现~

代码如下

    void maopao2(int a[], int size)  
    {  
        bool flag = true;  
        for (int i = 0; i < size -1; i++)  
        {  
            // 每次先重置为false  
            flag = false;  
            for (int j = size - 1; j > i ; j--)  
            {  
                if (a[j-1] > a[j])  
                {  
                    int temp = a[j-1];  
                    a[j-1] = a[j];  
                    a[j] = temp;  
      
                    flag = true;  
                }  
            }  
            // 如果上一次扫描没有发生交换,则说明数组已经全部有序,退出循环  
            if (!flag)  
                break;  
        }  
    }  

优化二

原理

在第一步优化的基础上发进一步思考:如果R[i..n]已是有序区间,上次的扫描区间是R[0..i],记上次扫描时最后 一次执行交换的位置为lastSwapPos,则lastSwapPos在o与i之间,不难发现R[lastSwapPos..i]区间也是有序的,否则这个区间也会发生交换;所以下次扫描区间就可以由R[0..i] 缩减到[0..lastSwapPos]。

例如: 

              一组无序数:4,6,3,2,7,9,8

第一次排序完毕后是:4,3,2,6,7,8,第一次执行交换的位置为lastSwapPos=6

第二次排序完毕后是:3,2,4,6,78,9  第二次执行交换的位置为lastSwapPos=2

第二次执行交换的位置为lastSwapPos= 2,第3位,第4位没有执行交换,因为已经是有序,所以第三次交换的扫描区就可以有【0-4】变为【0-2】

代码如下

void maopao3(int a[], int size)  
{  
    int lastSwapPos = 0;  
    for (int i = 0; i < size - 1; i++)  
    {  
        lastSwapPos 0;  
        for (int j = 1; j <lastSwapPos; j++)  
        {  
            if (a[j] > a[j + 1])  
            {  
                int temp = a[j];  
                a[j] = a[j+1];  
                a[j+1] = temp;  
  
                lastSwapPosTemp = j+1;  
            }  
        }  
        if (lastSwapPos == 0)  
            break;          
    }  
}  

结语

以上是对于有特殊情况的无序数列,用冒泡排序法时候的优化,优化后程序的运行时间会明显减少。交换排序除了冒泡排序外,还有一种快速排序,实质上也是对冒泡排序的一种改进,下次我们再接着继续……

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子松的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值