内容简介:排序算法中最最常见也算是入门的一个排序算法就是冒泡排序。这篇文章我们就来好好地写写这个冒泡排序算法,以及冒泡排序呢的改进算法。既然普通的冒泡排序只适合用于排序入门,那这冒泡排序是否可以进行改进进行实际应用呢?这里我们就来进行冒泡排序改进。上面的比较次数非常的不合理,就算是正常的有序依然会进行比较N*(N-1)/2次,那我们就可以通过标记当前已经有序则停止进行后续无用的比较,跳出循环。具体代码如下:上面的改进方法,是根据上一轮排序有没有发生数据交换作为标识,进一步思考,如果上一轮排序中,只有后一段的几个元素
前言
排序算法中最最常见也算是入门的一个 排序 算法就是冒泡排序。这篇文章我们就来好好地写写这个冒泡排序算法,以及冒泡排序呢的改进算法。
传统冒泡算法
static int[] array = {100,1,5,4,11,2,20,18,89,34,20,34};
@Test
public void bubbleSortNormal(){
int temp;
int len = array.length;
for(int i=0;i<len-1;i++){
for(int j=1;j<len-i;j++){
if(array[j-1]>array[j]){
temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
}
}
System.out.print("第"+(i+1)+"轮排序结果:");
display();
}
}
分析:
上面的算法代码非常好理解,我们现在来分析一下这个算法的时间复杂度:
(N-1)+ (N-2)+ (N-3)+ ...1=N*(N-1)/2;
因为只有在前面的元素比后面的元素大时才交换数据,所以交换的次数少于比较的次数。如果数据是随机的,大概有一半数据需要交换,则交换的次数为N^2/4(不过在最坏情况下,即初始数据逆序时,每次比较都需要交换)。
交换和比较的操作次数都与N^2成正比,由于在大O表示法中,常数忽略不计,冒泡排序的时间复杂度为O(N^2)。
O(N^2)的时间复杂度是一个比较糟糕的结果,尤其在数据量很大的情况下。所以普通冒泡排序通常不会用于实际应用。
改进冒泡排序版本1
既然普通的冒泡排序只适合用于排序入门,那这冒泡排序是否可以进行改进进行实际应用呢?这里我们就来进行冒泡排序改进。上面的比较次数非常的不合理,就算是正常的有序依然会进行比较N*(N-1)/2次,那我们就可以通过标记当前已经有序则停止进行后续无用的比较,跳出循环。具体代码如下:
static int[] array = {100,1,5,4,11,2,20,18,89,34,20,34};
@Test
public void bubbleSortPlusOne(){
int temp;
int len = array.length;
for(int i=0;i<len-1;i++){
boolean exchange = false;
for(int j=1;j<len-i;j++){
//如果前一位大于后一位,交换位置
if(array[j-1]>array[j]){
temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
//发生了交换操作
if(!exchange){ exchange =true;}
}
}
System.out.print("第"+(i+1)+"轮排序结果:");
display();
//如果上一轮没有发生交换数据,证明已经是有序的了,结束排序
if(!exchange){ break;}
}
}
分析:
加入标志性变量exchange,用于标志某一趟排序过程中是否有数据交换,如果进行某一趟排序时并没有进行数据交换,则说明数据已经按要求排列好,可立即结束排序,避免不必要的比较过程。
进一步升级冒泡排序
上面的改进方法,是根据上一轮排序有没有发生数据交换作为标识,进一步思考,如果上一轮排序中,只有后一段的几个元素没有发生数据交换,是不是可以判定这一段不用在进行比较了呢?答案是肯定的。
@Test
public void bubbleSortImprovement(){
int temp;
int counter = 1;
int endPoint = array.length-1;
while(endPoint>0){
int pos = 1;
for(int j=1;j<=endPoint;j++){
if(array[j-1]>array[j]){
temp= array[j-1];
array[j-1]= array[j];
array[j]= temp;
pos= j;
}
}
endPoint= pos-1;
System.out.print("第"+counter+"轮排序结果:");
display();
counter++;
}
}
分析:
设置一个pos指针,pos后面的数据在上一轮排序中没有发生交换,下一轮排序时,就对pos之后的数据不再比较。
冒泡排序改进
我们是否可以通过正向找寻最大值,反向找寻最小值把这个排序完成呢?答案是肯定的,接下来我们通过算法进行分析:
@Test
public void bubbleSortImprovementPlus(){
int temp;
int low = 0;
int high = array.length-1;
int counter = 1;
while(low<high){
for(int i=low;i<high;++i){
if(array[i]>array[i+1]){
temp= array[i];
array[i]= array[i+1];
array[i+1]= temp;
}
}
--high;
for(int j=high;j>low;--j){
if(array[j]<array[j-1]){
temp= array[j];
array[j]= array[j-1];
array[j-1]= temp;
}
}
++low;
System.out.print("第"+counter+"轮排序结果:");
display();
counter++;
}
}
分析:
传统的冒泡算法每次排序只确定了最大值,我们可以在每次循环之中进行正反两次冒泡,分别找到最大值和最小值,如此可使排序的轮数减少一半。
Linux公社的RSS地址 : https://www.linuxidc.com/rssFeed.aspx
本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-11/155585.htm
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 算法之常见排序算法-冒泡排序、归并排序、快速排序
- 快速排序算法,C语言快速排序算法深入剖析
- 排序算法下——桶排序、计数排序和基数排序
- 数据结构和算法面试题系列—排序算法之快速排序
- 数据结构和算法面试题系列—排序算法之基础排序
- 图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Mastering Regular Expressions, Second Edition
Jeffrey E F Friedl / O'Reilly Media / 2002-07-15 / USD 39.95
Regular expressions are an extremely powerful tool for manipulating text and data. They have spread like wildfire in recent years, now offered as standard features in Perl, Java, VB.NET and C# (and an......一起来看看 《Mastering Regular Expressions, Second Edition》 这本书的介绍吧!