声明:和小强一起学习数据结构java版系列文章都是小强在学习程杰先生《大话数据结构》的过程中写的,因为程杰先生的《大话数据结构》是C语言版本的,小强只不过将C版本的程序在java版本中调通,然后写下来。
冒泡排序
1. 概念:
依次比较相邻位置上的两个数,如果反序则交换,直到没有反序记录为止。由于在排序的过程中总是小数往前放,大数往后方,相当于气泡的上升,所以称作冒泡排序。
2. 验证代码
由于冒泡排序有三种不同的算法,在此验证三种不同算法的代码相同,所以就总的写在这里,如下所示:
publicclassJava_Sort {
public static void main(String[] args) {
int[]values={3,15,4,9,232,24,9978,5,0};
System.out.print("排序前顺序为:");
for(int i=0;i<values.length;i++){
System.out.print(" "+values[i]);
}
BubbleSort.sort1(values); //验证算法1时用
//BubbleSort.sort1(values);//验证算法2时用
//BubbleSort.sort1(values);//验证算法3时用
System.out.print("\n");
System.out.print("排序后顺序为:");
for(int i=0;i<values.length;i++){
System.out.print(" "+values[i]);
}
}
}
3. 程序示例与讲解
1) 先看最容易理解的排序
public class BubbleSort {
publicstaticvoidsort1(int[]values){
//定义临时变量,作为数据调换的桥梁
int temp=0;
//values.length:等待排序数据个数,也就是循环的次数
//让每一个位置上的数和它后边的所有数比较,反序则交换
for(inti =0 ;i<=values.length-1;i++){
for(int j=i+1;j<=values.length-1;j++){
if(values[i]>values[j]){
temp=values[i];
values[i]=values[j];
values[j]=temp;
}
}
}
}
}
验证结果:
排序前顺序为: 3 15 4 9 232 24 9978 5 0
排序后顺序为: 0 3 4 5 9 15 24 232 9978
图示说明(在图示中只显示两次的排列):
算法说明:这段代码从严格意义上说,不算是标准的冒泡算法,因为它不满足“相邻位置上两个数”的冒泡排序思想,它更应该是最简单的交换排序而已。此算法的思想是:让每一个位置上的数,跟它后边的所有数相比较,反序则交换位置,从图中可以看到,以位置为基准的这种排序方法,每次排序之后,对其他位置上的数的排列没有帮助(例如i=0时,将3给换到了最后一位),这种算法效率比较低。
2) 正宗的冒泡排序
publicclassBubbleSort {
publicstatic void sort2(int[] values){
//定义临时变量,作为数据调换的桥梁
int temp=0;
//values.length:等待排序数据个数,也就是循环的次数
//从第最后一个位置开始,每一个位置和它前边的比较,反序则交换。
for(int i =0;i<values.length-1;i++){
for(int j=values.length-1;j>0;j--){//j从后边往前循环
if(values[j]<values[j-1]){//若后者小于前者,则交换
temp=values[j-1];
values[j-1]=values[j];
values[j]=temp;
}
}
}
}
}
验证结果:
排序前顺序为: 3 15 4 9 232 24 9978 5 0
排序后顺序为: 0 3 4 5 9 15 24 232 9978
图示说明:
算法说明:
此算法从最后一个位置上的数开始往上,相邻的两个数相比较,小的向上升,大的向下沉,犹如气泡一样,慢慢的浮到上边。
3) 冒泡排序优化
假如待排序序列如下{2,1,3,4,5,6,7,8,9},我们按照上边的两个方法排序可以吗?当然可以,不过仔细观察我们会发现:除了第一和第二位置需要交换之外,别的都已经是正常顺序了,可如果按照我们上面的方法,要将整个序列一遍遍循环,显然没有必要。为此,我们可以给上面代码中增加一个标记,来加以改进。
public static void sort3(int[] values){
int temp=0;
Booleanflag=true;//增加flag标志
//在进入循环之前首先判断flag标志是否为true
for(int i=0;i<(values.length-1)&&flag;i++){
flag=false;
for(int j=values.length-1;j>0;j--){
if(values[j]<values[j-1]){
temp=values[j-1];
values[j-1]=values[j];
values[j]=temp;
flag=true;//如果有数据交换,flag=true
}
}
}
}
验证结果:
排序前顺序为: 1 0 2 3 4 5 6 7 8 9
排序后顺序为: 0 1 2 3 4 5 6 7 8 9