数据结构与算法之冒泡排序及优化
一 基本介绍
(1)冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较
相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
(2)优化:
因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在
排序过程中设置一个标志 flag 判断元素是否进行过交换。从而减少不必要的比较。(这里说的优化,可以在冒泡排
序写好后,在进行)
二 演示冒泡过程
小结上面的图解过程:
(1) 一共进行 数组的大小-1 次 大的循环(n-1)
(2)每一趟排序的次数在逐渐的减少(n-1-i)
(3) 如果我们发现在某趟排序中,没有发生一次交换, 可以提前结束冒泡排序。这个就是优化
演示代码实现
/*
// 第一趟排序,就是将第一大的数排在倒数第一位
for (int j = 0; j < arr.length - 1 - 0 ; 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 - 1 - 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 - 1 - 2; j++) { // 如果前面的数比后面的数大,则交换
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println("第三趟排序后的数组");
ystem.out.println(Arrays.toString(arr));
// 第四趟排序,就是将第 4 大的数排在倒数第 4 位
for (int j = 0; j < arr.length - 1 - 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)); */
}
三 冒泡排序代码实现
package com.datastrucate.sort;
import java.util.Arrays;
/**
* ClassName:BubbleSort
* Package:com.datastrucate.sort
* Description:
* 冒泡排序及优化
* 思路:两层循环,相邻两数比较大小,n代表数组容量,i代表外部循环次数
* 外部循环次数:n-1,对应比较趟数
* 内部循环次数:n-1-i,对应每趟比较次数
* 空间复杂度:O(n^2)
*
* @Date:2021/3/3 16:08
* @Author:hm
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = new int [80000];
//生成8万个随机数
for (int i = 0;i < 80000;i++){
arr[i] = (int)(Math.random()*80000);//范围为[0,80000)
}
long start = System.currentTimeMillis();
System.out.println("排序前时间:"+start+"秒");
bubbleSort(arr);
long end = System.currentTimeMillis();
System.out.println("排序后时间:"+end+"秒");
System.out.println("用时:"+(end-start)+"秒");
}
/**
* 冒泡排序方法
* 外部循环次数:n-1,对应比较趟数
* 内部循环次数:n-1-i,对应每趟比较次数
* @param arr
*/
private static void bubbleSort(int[] arr) {
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));
//每一趟比较后判断flag
if (!flag){
//没有交换过
break;
}else {
//比较过,需重置flag为flase,用于下一趟比较
flag = false;
}
}
}
}