博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
冒泡排序法算法分析
阅读量:6311 次
发布时间:2019-06-22

本文共 2257 字,大约阅读时间需要 7 分钟。

 

 

冒泡排序算法的运作如下:

1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

具体如何进行移动呢?让我们来看一个例子:

有8个数组成上面一个无序数列:5,8,6,5,9,2,1,7,目标是从小到大排序。

按照冒泡排序的思想,过程如下:
首先让5和8比较,8比5大,故两者不进行交换。
接下来8和6比较,8比6大,两者进行交换。

继续8和3比较,交换8和3的位置。

继续8和9比较,9比8大,两者不进行交换。

然后比较9和2,9比2大,两者进行交换。

接下来比较9和1,9比1大,两者进行交换。

 

在最后比较9和7,9大于7,两者进行交换。

经过上面的冒泡排序的第一轮运作。数列最右侧元素可以认为是一个有序区域,有序区域目前只有一个元素。

接下来进行如上的7轮排序得到最终的有序数列:

第六轮、第七轮、第八轮排序:

第六轮排序:

 

 第七轮排序:

 第八轮排序:

问题分析:在6-8轮中我们待排序的数列早就已经是有序的数列的,可是冒泡排序依旧进行比较。

算法改进1:在进行每一轮的排序工作时判断数列是否有序,如已经是有序的数列则将排序工作提早结束。
算法改进2:算法改进的关键点在于对数列有序区的界定。
按照冒泡排序的逻辑,有序区的长度和排序的轮数是相等的。比如第一轮排序过后的有序长度为1,第二轮排序后有序长度是2……但是实际情况是这样子的吗?实际上,数列真正的有序区可能会大于这个长度。那么后面的许多元素的比较是没有意义的。解决思路:在每一轮排序的最后,记录下最后一个元素交换的位置,那个位置也就是无序数列的边界,再往后就是有序区了。

基本的冒泡排序代码:

//冒泡排序函数  版本1

private static void SortBubbling(int[] arr_Native) {
int temp;
for (int i = 0; i < arr_Native.length-1; i++) { //外循环只需要比较arr.length-1次就可以
for (int j = 0; j < arr_Native.length-i-1; j++) { //内循环需要比较arr_Native.length-i-1
if (arr_Native[j]>arr_Native[j+1]) {
temp=arr_Native[j];
arr_Native[j]=arr_Native[j+1];
arr_Native[j+1]=temp;
}
}
}
}

算法改进1后的代码:

//冒泡排序函数 版本2
//利用boolean变量isSored作为标记。如果在本轮排序中,元素有交换,说明数列无序;如果没有元素交换,说明数列已然有序,直接跳出大循环
private static void SortBubbling2(int[] arr_Native) {
int temp;
for (int i = 0; i < arr_Native.length-1; i++) { //外循环只需要比较arr.length-1次就可以
boolean isSored = true;
for (int j = 0; j < arr_Native.length-i-1; j++) { //内循环需要比较arr_Native.length-i-1
if (arr_Native[j]>arr_Native[j+1]) {
temp=arr_Native[j];
arr_Native[j]=arr_Native[j+1];
arr_Native[j+1]=temp;
isSored = false;
}
}
if (isSored) {
break;
}
}
}
算法改进2后的代码:

private static void SortBubbling3(int[] arr_Native) {

int temp;
//记录最后一次交换的位置
int lastExchangeIndex = 0;
//无序数列的边界,每次比较只需要比到这里为止
int sortBorder = arr_Native.length-1;
for (int i = 0; i < arr_Native.length-1; i++) { //外循环只需要比较arr.length-1次就可以
boolean isSored = true;
for (int j = 0; j < sortBorder; j++) { //内循环需要比较arr_Native.length-i-1
if (arr_Native[j]>arr_Native[j+1]) {
temp=arr_Native[j];
arr_Native[j]=arr_Native[j+1];
arr_Native[j+1]=temp;
isSored = false;
lastExchangeIndex = j;
}
}
sortBorder=lastExchangeIndex;
if (isSored) {
break;
}
}
}

 

转载于:https://www.cnblogs.com/taowangwang/p/9530106.html

你可能感兴趣的文章
Lucene基础学习笔记
查看>>
使用Monkeyrunner进行Android自动化的总结
查看>>
Linux SSH登录慢案例分析
查看>>
典型的垃圾收集器
查看>>
输入数字动态创建行(二)
查看>>
js动画实现&&回调地狱&&promise
查看>>
生信算法实践
查看>>
创建一个Scalar-valued Function函数来实现LastIndexOf
查看>>
Pgsql和Mysql的对比
查看>>
Introduction to dnorm, pnorm, qnorm, and rnorm for new biostatisticians
查看>>
Swift中的Any 与 AnyObject、AnyClass的区别?
查看>>
BBS论坛(九)
查看>>
Spring与SpringMVC的区别
查看>>
android排除报很多错方法 Execution failed for task ':app:compileDebugJavaWithJavac' in Android Studio...
查看>>
唯品会的Service Mesh三年进化史
查看>>
Styles and Themes
查看>>
国签证面试时的注意事项
查看>>
XAMPP下pear安装
查看>>
简易版ubtuntu下架设dns服务器
查看>>
Flash学习资源下载列表
查看>>