C/C++冒泡排序4种优化方法
冒泡排序应该是大多数人接触的第一种排序方法,虽然它的时间复杂度为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种优化方法相关推荐
- 快速排序的5种优化方法
三种快速排序以及快速排序的优化 1.快速排序的基本思想: 快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小.之后分别对这两部分记录继续进行排 ...
- Beam Search 及5种优化方法
文章目录 Beam Search 及优化 1. Review Beam Search 2. Beam Search Refinement 2.1 Hypothesis filtering 2.2 No ...
- python冒泡排序_5种python方法实现冒泡排序可视化:Bubble Sort Visualizer
1 说明: ===== 1.1 冒泡排序: 1.1.1 原理:比较两个相邻的元素,将值大的元素交换至右端. 1.1.2 来源:由来是因为越大的元素会经由交换慢慢"浮"到数列的顶端, ...
- 爬山算法改进粒子群求解测试测试函数shubert,测试函数的100种优化方法之14
爬山算法粒子群求解测试测试函数 shubert函数属于周期性多峰函数,如图1所示拥有多个全局最优值,如图二所示在一个周期内只有一个全局最优值,局部最优解较多,适合测试算法的收敛性能,粒子群算法是一种收 ...
- 基于MATLAB樽海鞘算法SSA(麻雀算法(十一)也简称SSA)的Eggholeer函数优化,测试函数的100种优化方法之十二
樽海鞘算法优化 Eggholder测试函数 樽海鞘算法SSA(麻雀算法也简称SSA,如果想了解麻雀算法,看方法十一)模拟了樽海鞘的聚集成链的生活习性而提出的优化算法,是近几年刚推出的新算法之一.算法将 ...
- 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 ...
- 几种优化方法的Matlab实现
https://blog.csdn.net/u012938704/article/details/79979579
- 几种常用的优化方法梯度下降法、牛顿法、)
几种常用的优化方法 1. 前言 熟悉机器学习的童鞋都知道,优化方法 ...
- 快排算法及常见两种常见优化方法
简书同步发布 正常快排 最近在找实习,然而我觉得博客还是要坚持日更,我相信时间总是挤出来的,不扯淡了,快排这是个面试常考题,今天主要着重于讲他的优化方法,那我就直接先贴快排代码,再来细细道来我所知道的 ...
最新文章
- Microbiome:掠食性粘细菌通过调节土壤微生物群落来控制黄瓜枯萎病
- linux6.6挂载u盘失败,mini2440 Linux系统自动挂载U盘与SD卡失败 解决方法
- 图像还可以这样玩!如何用波的算法处理图像
- 杭电OJ1002大数据相加
- win2012iis php,Win2012 R2 IIS8.5+PHP(FastCGI)+MySQL运行环境搭建教程
- php3d饼状图,php 生成饼图 三维饼图
- ubuntu 12 04下安装JDK7
- nginx 多个root_dockerfile定制自己的nginx
- laravel 图片
- 一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用
- java类加载器说法正确的_Java中的类加载器
- 关于CSS中背景图片透明度问题
- 研究生学术英语写作网课答案
- yocto相关class总结
- PowerDesigner清理注册表
- 2014年度大疆创新笔试题心得
- Prometheus + Grafana 图形化监控实践
- 四川大学软件学院 2017级系统级编程 复习知识点-很零碎的那种
- 7-38 实验7_3_奇数偶数 (100 分)奇数偶数排序
- 中职学校计算机应用基础学什么,中职计算机应用基础课程教学分析
热门文章
- 镶嵌数据集工具小结(五)镶嵌数据集的属性 Ⅱ
- 域分析工具BloodHound的使用
- 机械革命z2黑苹果双系统改造计划
- 用python做毕业设计多少钱_我的毕业设计是利用Python做一个淘淘购物系统!
- 深入浅出TensorFlow2函数——tf.keras.layers.Dense
- P1091 [NOIP2004 提高组] 合唱队形(动态规划+LIS)
- Java之单元测试和安全规范
- python 3 中的pickle模块 阿波的博客
- HTML+CSS+JavaScript制作浪漫烟花告白(程序员撩妹手到擒来~)
- Spring Cloud Alibaba - Gateway 入门案例(二)(Gateway 整合 nacos /(非阿里组件))