冒泡排序应该是大多数人接触的第一种排序方法,虽然它的时间复杂度为O(n^2),但是它简单易懂,代码复杂度低,所以仍有很大的用武之地。最近在总结排序算法,决定重温下冒泡排序,以及它的优化方法。

冒泡排序的原理以及排序过程参考:冒泡排序,三分钟彻底理解冒泡排序

冒泡排序的一些属性:

算法 最好时间 最坏时间 平均时间 额外空间 稳定性
冒泡 O(n) O(n2) O(n2) 1 稳定

普通冒泡排序:

void myBubleSort1(int * nums, int len) {int temp;for (int i = 0; i < len; ++i) {for (int j = 0; j < len-i-1; ++j) {if (nums[j] > nums[j+1]) {temp = nums[j];nums[j] = nums[j+1];nums[j+1] = temp;}}}
}

优化1:使用异或运算交换两个数

在冒泡循环中,我们要交换两个变量的值,通常是使用一个临时变量来辅助交换过程。在C++中可以使用swap()函数。如果交换的值是整数,我们可以省略这个临时变量,使用异或运算符交换两个变量的值:

a和b的值进行交换:

a = a^b;
b = b^a;
a = a^b;

代码实现:

void myBubleSort2(int * nums, int len) {for (int i = 0; i < len; ++i) {for (int j = 0; j < len - i - 1; ++j) {if (nums[j] > nums[j + 1]) {nums[j] = nums[j] ^ nums[j + 1];nums[j + 1] = nums[j + 1] ^ nums[j];nums[j] = nums[j] ^ nums[j + 1];}}}
}

优化2:设置排序完成的标志

冒泡排序需要有两层循环,无论数组是否排好序,都会完成这两层循环,对于最差的情况,比如[9,8,7,6,5,4],对其进行升序排序,这两层循环必不可少;但是对于[9,1,2,3,4,5]这种情况,第一遍循环结束后,整个数组就已经是升序排列的了,但是普通的冒泡排序还会继续进行循环遍历比较,这就对做了不少无用功。所以需要设置一个排序完成的标志,如果排序已经完成,就没必要再继续循环遍历了,直接跳出循环。

void myBubleSort3(int * nums, int len) {bool isSwapped;for (int i = 0; i < len; ++i) {isSwapped = false;for (int j = 0; j < len - i - 1; ++j) {if (nums[j] > nums[j + 1]) {nums[j] = nums[j] ^ nums[j + 1];nums[j + 1] = nums[j + 1] ^ nums[j];nums[j] = nums[j] ^ nums[j + 1];isSwapped = true;}}if(!isSwapped) break;}
}

优化3:跳过无意义的比较

优化一仅仅适用于连片有序而整体无序的数据(例如:1, 2,3 ,4 ,7,6,5)。但是对于前面大部分是无序而后边小半部分有序的数据(1,2,5,7,4,3,6,8,9,10)排序效率也不可观,对于种类型数据,我们可以继续优化。既我们可以记下最后一次交换的位置,后边没有交换,必然是有序的,然后下一次排序从第一个比较到上次记录的位置结束即可。

void myBubleSort4(int * nums, int len) {bool isSwapped;int lastSwap = 0;int k = len - 1;for (int i = 0; i < len; ++i) {isSwapped = false;for (int j = 0; j < k; ++j) {if (nums[j] > nums[j + 1]) {nums[j] = nums[j] ^ nums[j + 1];nums[j + 1] = nums[j + 1] ^ nums[j];nums[j] = nums[j] ^ nums[j + 1];isSwapped = true;//lastSwap之后的数都是排好序的lastSwap = j;}}if (!isSwapped) break;k = lastSwap;}
}

优化4

优化3的效率有很大的提升,还有一种优化方法可以继续提高效率。大致思想就是一次排序可以确定两个值,正向扫描找到最大值交换到最后,反向扫描找到最小值交换到最前面。例如:排序数据1,2,3,4,5,6,0

void BubbleSort(int arr[], int len)
{int i = 0;int j = 0;int n = 0;//同时找最大值的最小需要两个下标遍历int flag = 0;int pos = 0;//用来记录最后一次交换的位置int k = len - 1;for (i = 0; i < len - 1; i++)//确定排序趟数{pos = 0;flag = 0;//正向寻找最大值for (j = n; j < k; j++)//确定比较次数{if (arr[j]>arr[j + 1]){//交换int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;flag = 1;//加入标记pos = j;//交换元素,记录最后一次交换的位置}}if (flag == 0)//如果没有交换过元素,则已经有序,直接结束{return;}k = pos;//下一次比较到记录位置即可//反向寻找最小值for (j = k; j > n; j--){int tmp = arr[j];arr[j] = arr[j - 1];arr[j - 1] = tmp;flag = 1;}n++;if (flag == 0)//如果没有交换过元素,则已经有序,直接结束{return;}}
}

参考文章:【排序】:冒泡排序以及三种优化

C/C++冒泡排序4种优化方法相关推荐

  1. 快速排序的5种优化方法

    三种快速排序以及快速排序的优化 1.快速排序的基本思想: 快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小.之后分别对这两部分记录继续进行排 ...

  2. Beam Search 及5种优化方法

    文章目录 Beam Search 及优化 1. Review Beam Search 2. Beam Search Refinement 2.1 Hypothesis filtering 2.2 No ...

  3. python冒泡排序_5种python方法实现冒泡排序可视化:Bubble Sort Visualizer

    1 说明: ===== 1.1 冒泡排序: 1.1.1 原理:比较两个相邻的元素,将值大的元素交换至右端. 1.1.2 来源:由来是因为越大的元素会经由交换慢慢"浮"到数列的顶端, ...

  4. 爬山算法改进粒子群求解测试测试函数shubert,测试函数的100种优化方法之14

    爬山算法粒子群求解测试测试函数 shubert函数属于周期性多峰函数,如图1所示拥有多个全局最优值,如图二所示在一个周期内只有一个全局最优值,局部最优解较多,适合测试算法的收敛性能,粒子群算法是一种收 ...

  5. 基于MATLAB樽海鞘算法SSA(麻雀算法(十一)也简称SSA)的Eggholeer函数优化,测试函数的100种优化方法之十二

    樽海鞘算法优化 Eggholder测试函数 樽海鞘算法SSA(麻雀算法也简称SSA,如果想了解麻雀算法,看方法十一)模拟了樽海鞘的聚集成链的生活习性而提出的优化算法,是近几年刚推出的新算法之一.算法将 ...

  6. 1D/1D动态规划的三种优化方法

    1D/1D1D/1D1D/1D动态规划 形如dp[i]=min{dp[j]+w(j,i)}(Li≤j≤Ri)dp[i]=min\{dp[j]+w(j,i)\} (L_i\leq j\leq R_i)d ...

  7. 几种优化方法的Matlab实现

    https://blog.csdn.net/u012938704/article/details/79979579

  8. 几种常用的优化方法梯度下降法、牛顿法、)

                                                                       几种常用的优化方法 1. 前言 熟悉机器学习的童鞋都知道,优化方法 ...

  9. 快排算法及常见两种常见优化方法

    简书同步发布 正常快排 最近在找实习,然而我觉得博客还是要坚持日更,我相信时间总是挤出来的,不扯淡了,快排这是个面试常考题,今天主要着重于讲他的优化方法,那我就直接先贴快排代码,再来细细道来我所知道的 ...

最新文章

  1. Microbiome:掠食性粘细菌通过调节土壤微生物群落来控制黄瓜枯萎病
  2. linux6.6挂载u盘失败,mini2440 Linux系统自动挂载U盘与SD卡失败 解决方法
  3. 图像还可以这样玩!如何用波的算法处理图像
  4. 杭电OJ1002大数据相加
  5. win2012iis php,Win2012 R2 IIS8.5+PHP(FastCGI)+MySQL运行环境搭建教程
  6. php3d饼状图,php 生成饼图 三维饼图
  7. ubuntu 12 04下安装JDK7
  8. nginx 多个root_dockerfile定制自己的nginx
  9. laravel 图片
  10. 一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用
  11. java类加载器说法正确的_Java中的类加载器
  12. 关于CSS中背景图片透明度问题
  13. 研究生学术英语写作网课答案
  14. yocto相关class总结
  15. PowerDesigner清理注册表
  16. 2014年度大疆创新笔试题心得
  17. Prometheus + Grafana 图形化监控实践
  18. 四川大学软件学院 2017级系统级编程 复习知识点-很零碎的那种
  19. 7-38 实验7_3_奇数偶数 (100 分)奇数偶数排序
  20. 中职学校计算机应用基础学什么,中职计算机应用基础课程教学分析

热门文章

  1. 镶嵌数据集工具小结(五)镶嵌数据集的属性 Ⅱ
  2. 域分析工具BloodHound的使用
  3. 机械革命z2黑苹果双系统改造计划
  4. 用python做毕业设计多少钱_我的毕业设计是利用Python做一个淘淘购物系统!
  5. 深入浅出TensorFlow2函数——tf.keras.layers.Dense
  6. P1091 [NOIP2004 提高组] 合唱队形(动态规划+LIS)
  7. Java之单元测试和安全规范
  8. python 3 中的pickle模块 阿波的博客
  9. HTML+CSS+JavaScript制作浪漫烟花告白(程序员撩妹手到擒来~)
  10. Spring Cloud Alibaba - Gateway 入门案例(二)(Gateway 整合 nacos /(非阿里组件))