冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始), 依次比较
相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。为什么可以优化?
因为排序的过程中,各元素不断接近自己的位置, 如果一趟比较下来没有进行过交换 , 就说明序列有序,因此要在排序过程中设置一个标志 flag 判断元素是否进行过交换。从而减少不必要的比较。(这里说的优化,可以在冒泡排序写好后,在进行)
为了容量理解,在这把冒泡排序的演变过程,给大家演示
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {3,9,-1,10,-2};
// 展示冒泡排序的演变过程 比较arr.length-1 次 就可以得出结果
/**
* 第一趟排序后的数组
* [3, -1, 9, -2, 10]
* 第二趟排序后的数组
* [-1, 3, -2, 9, 10]
* 第三趟排序后的数组
* [-1, -2, 3, 9, 10]
* 第四趟排序后的数组
* [-2, -1, 3, 9, 10]
*/
// 第一趟排序 就是将最大的数字放到最后
int temp = 0; // 临时变量
for(int j = 0; j < arr.length - 1; j++ ){
//如果前面的数比后面的数大,则交换
if(arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j + 1] = temp;
}
}
System.out.println("第一趟排序后的数组");
System.out.println(Arrays.toString(arr));
// 第二趟排序 , 把第二大的数放在倒数第二位 最后一个数字不参与排序
for(int j = 0; j < arr.length - 2; j++ ){
if(arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j + 1] = temp;
}
}
System.out.println("第二趟排序后的数组");
System.out.println(Arrays.toString(arr));
// 第三趟排序 , 把第三大的数放在倒数第三位 最后两个数字不参与排序
for(int j = 0; j < arr.length - 3; j++ ){
if(arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j + 1] = temp;
}
}
System.out.println("第三趟排序后的数组");
System.out.println(Arrays.toString(arr));
// 第四趟排序 , 把第四大的数放在倒数第四位 最后三个数字不参与排序
for(int j = 0; j < arr.length - 4; j++ ){
if(arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j + 1] = temp;
}
}
System.out.println("第四趟排序后的数组");
System.out.println(Arrays.toString(arr));
}
}
合并演变过程:
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {3, 9, -1, 10, -2};
int temp = 0; // 临时变量
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("冒泡排序后的数组");
System.out.println(Arrays.toString(arr));
}
}
输出:
接下来是优化代码环节:
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {3, 9, -1, 10, -2};
int temp = 0; // 临时变量
boolean flag=false;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1])
{
flag=true;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println("第"+(i+1)+"趟排序后的数组");
System.out.println(Arrays.toString(arr));
if (!flag){ //在一趟排序中,一次交换都没有发生过
break;
}else flag=false;
}
}
}
将 int arr[] = {3, 9, -1, 10, -2}换成 int arr[] = {3, 9, -1, 10, 20}
输出结果:
将前面的冒泡排序算法,封装成一个方法,来测试性能
public class BubbleSort {
public static void main(String[] args) {
int arr[]=new int[80000];
for (int i=0;i<80000;i++){
arr[i]=(int) (Math.random()*8000000);
}
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间是="+date1Str);
//测试冒泡排序的性能
bubbleSort(arr);
Date date2 = new Date();
String date2Str = simpleDateFormat.format(date2);
System.out.println("排序后的时间是="+date2Str);
}
//将冒泡排序算法封装成一个方法
public static void bubbleSort(int []arr){
//冒泡排序 的时间复杂度是o(n^2) 自己写出
int temp = 0; // 临时变量
boolean flag=false;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1])
{
flag=true;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if (!flag){ //在一趟排序中,一次交换都没有发生过
break;
}else flag=false;
}
}
}