冒泡排序思路:
依次比较数组中相邻两个元素的大小,若a[i]>a[i+1],则交换两个元素,两两都比较一遍称为一轮冒泡,结果是让最大的元素排到最后
重复以上步骤,至到整个数组有序
优化方式:每轮冒泡时,最后一次交换的索引可以作为下一轮冒泡的比较次数,如果这个值为0,表示整个数组有序,直接退出外循环即可
一、冒泡排序初步实现代码
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] a = {5,9,7,4,1,3,2,8};
bubble(a);
}
public static void bubble(int[] a){
for (int j = 0; j < a.length-1; j++) {
for (int i = 0; i < a.length - 1; i++) {
if (a[i] > a[i + 1]) {
swap(a, i, i + 1);
}
}
System.out.println("第"+j+"轮冒泡排序"+ Arrays.toString(a));
}
}
public static void swap(int[] a,int i,int j){
int temp = a[i];
a[i]=a[j];
a[j]=temp;
}
}
实现结果:
二、优化:减少比较次数
未优化前,每次需要比较相同次数,浪费时间
因为每次冒泡排序后,最后一个元素的位置被排好了,因此比较次数应根据排序轮数递减
代码如下:
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] a = {5, 9, 7, 4, 1, 3, 2, 8};
bubble(a);
}
public static void bubble(int[] a) {
for (int j = 0; j < a.length - 1; j++) {
for (int i = 0; i < a.length - 1 - j; i++) {
System.out.println("比较次数" + i);
if (a[i] > a[i + 1]) {
swap(a, i, i + 1);
}
}
System.out.println("第" + j + "轮冒泡排序" + Arrays.toString(a));
}
}
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
三、优化:减少冒泡次数
可以发现,4、5、6的数组顺序已经排好,但却多比较了几轮,因此可以利用一个boolean变量来标记是否发生交换,如果发生交换则继续进行冒泡,如果没有发生交换,说明数组已经排好,退出循环
代码如下:
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] a = {5, 9, 7, 4, 1, 3, 2, 8};
bubble(a);
}
public static void bubble(int[] a) {
for (int j = 0; j < a.length - 1; j++) {
boolean swapped = false;
for (int i = 0; i < a.length - 1 - j; i++) {
System.out.println("比较次数" + i);
if (a[i] > a[i + 1]) {
swap(a, i, i + 1);
swapped = true;
}
}
System.out.println("第" + j + "轮冒泡排序" + Arrays.toString(a));
if(!swapped){
break;
}
}
}
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
结果如图,减少了排序次数
四、进一步优化
如果数组后面的数已经排好序,不必要继续进行冒泡,只需记录最后发生交换的元素索引下标即可,如果元素的下标为0,则排序结束
代码如下:
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] a = {5, 2, 7, 4, 1, 3, 8, 9};
bubble(a);
}
public static void bubble(int[] a) {
int j = 0;//记录比较次数
int n = a.length - 1;//循环需要比较的次数
while (true) {
int last = 0;//初始化索引下标
for (int i = 0; i < n; i++) {
System.out.println("比较次数" + i);
if (a[i] > a[i + 1]) {
swap(a, i, i + 1);
last = i;//如果发生交换,记录发生交换的下标,为下一次循环的中止
}
}
n = last;
System.out.println("第" + j + "轮冒泡排序" + Arrays.toString(a));
if (n == 0) {
break;
}
j++;//循环次数增加
}
}
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
结果: