基本思想
基本思想: 冒泡排序,类似于水中冒泡,较大的数沉下去,较小的数慢慢冒起来,假设从小到大,即为较大的数慢慢往后排,较小的数慢慢往前排。
直观表达,每一趟遍历,将一个最大的数移到序列末尾。
实例演示
排序的过程:两两比较,以第一趟排序的过程距离:
10跟1比较, 10>1, —》1 10
10跟35比较,10<35, —》1 10 35
35跟61比较,35<61, —》1 10 35 61
61跟89比较,61<89, —》1 10 35 61 89
89跟36比较,89>36, —》1 10 35 61 36 89
89跟55比较,89>55, —》1 10 35 61 36 55 89
到此第一趟排序结束,确定了最大数为89,放在了最后一个位置,后面的每一趟排序都是找到最大的数,将其放在序列末尾,直至第n-1次排序,确定了倒数第二个数和最后一个数的大小关系。
代码实现
基础实现
第一趟排序的实现:第一趟排序就是找出该序列中最大的一个数
package com.company.sort;
import java.util.Arrays;
public class Bubble {
public static void main(String[] args) {
//冒泡排序算法
//待排序数组
int[] list={10,1,35,61,89,36,55};
//临时变量,用作交换
int temp=0;
for(int j=0;j<list.length-1;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
}
}
结果:
第二趟排序:第二趟排序就是找出第二大的数。将第一趟找出的最大数不参与比较,用相同的方式比较剩下的数,找出最大的,注意这里的区别在list.length-1-1。
package com.company.sort;
import java.util.Arrays;
public class Bubble {
public static void main(String[] args) {
//冒泡排序算法
//待排序数组
int[] list={10,1,35,61,89,36,55};
//临时变量,用作交换
int temp=0;
//第一趟排序
for(int j=0;j<list.length-1;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
//第二趟排序
for(int j=0;j<list.length-1-1;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
}
}
结果:
因为选择的序列里面有七个数,所以最基础的冒泡排序需要进行六趟比较:
package com.company.sort;
import java.util.Arrays;
public class Bubble {
public static void main(String[] args) {
//冒泡排序算法
//待排序数组
int[] list={10,1,35,61,89,36,55};
//临时变量,用作交换
int temp=0;
//第一趟排序
for(int j=0;j<list.length-1;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
//第二趟排序
for(int j=0;j<list.length-1-1;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
//第三趟排序
for(int j=0;j<list.length-1-2;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
//第四趟
for(int j=0;j<list.length-1-3;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
//第五趟
for(int j=0;j<list.length-1-4;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
//第六趟
for(int j=0;j<list.length-1-5;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
}
}
结果:
从代码可以看出,这几次比较代码几乎就是相同的,除了j<list.length这个部分
可以将这六个单层循环用一个两个循环实现:
for(int i=0;i<list.length-1;i++){
for(int j=0;j<list.length-1-i;j++){
if(list[j]>list[j+1]){
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
}
结果:
代码优化
从上面排序的结果可以看出,使用的冒泡排序在第二轮得到的结果就是最终的排序结果,所以我们可以对算法进行优化,优化的思路如下:
当某一轮中没有出现交换元素次序的时候,得到的就是最终的排序结果
package com.company.sort;
import java.util.Arrays;
public class Bubble {
public static void main(String[] args) {
//冒泡排序算法
//待排序数组
int[] list={10,1,35,61,89,36,55};
//临时变量,用作交换
int temp=0;
//标志位,用于标记是否发生了交换元素
boolean flag=false;
for(int i=0;i<list.length-1;i++){
for(int j=0;j<list.length-1-i;j++){
if(list[j]>list[j+1]){
flag=true;
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
System.out.println(Arrays.toString(list));
if(!flag){
break;
}else{
flag=false;
}
}
}
}
如果某一次排序没有产生元素交换,那该次排序的结果就是最终结果。
注意这里没有使用没有元素交换的排序的上一次结果作为最终结果,因为若该序列本身为有序时,将不会有任何输出。代码如下:
package com.company.sort;
import java.util.Arrays;
public class Bubble {
public static void main(String[] args) {
//冒泡排序算法
//待排序数组
int[] list={1,2,3,4,5};
//临时变量,用作交换
int temp=0;
//标志位,用于标记是否发生了交换元素
boolean flag=false;
for(int i=0;i<list.length-1;i++){
for(int j=0;j<list.length-1-i;j++){
if(list[j]>list[j+1]){
flag=true;
temp=list[j+1];
list[j+1]=list[j];
list[j]=temp;
}
}
if(!flag){
break;
}else{
flag=false;
}
System.out.println(Arrays.toString(list));
}
}
}
结果:
结果没有输出,因为已经退出循环,没有进行打印。