- 原理
每次循环找出一个最大的元素(动态演示)
- 第一版冒泡
java
复制代码
public class Maopao1 {
public static void main(String[] args) {
long start= System.currentTimeMillis();
int[] arr2 = {11, 23, 69, 99, 1, 3, 45, 67, 5, 234, 678, 999, 7, 123};
int[] result = maopao(arr2);
System.out.println(Arrays.toString(result));
System.out.println(System.currentTimeMillis()-start);
}
private static int[] maopao(int[] arr2) {
for (int i = 0; i < arr2.length - 1; i++) {
for (int j = 0; j < arr2.length - 1; j++) {
if (arr2[j] > arr2[j + 1]) {
swap(arr2, j, j + 1);
}
}
System.out.println(Arrays.toString(arr2));
}
System.out.println("循环了" +( arr2.length-1) + "次");
return arr2;
}
public static void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
- 改进一:内层循环的次数与外层循环有关系,将a.length-1变成a.length-1-i,可以每次循环后减少一次循环次数。
java
复制代码
public class Maopao2 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
int[] arr2 = {11, 23, 69, 99, 1, 3, 45, 67, 5, 234, 678, 999, 7, 123};
int[] result = maopao(arr2);
System.out.println(Arrays.toString(result));
System.out.println(System.currentTimeMillis()-start);
}
private static int[] maopao(int[] arr2) {
for (int i = 0; i < arr2.length - 1; i++) {
for (int j = 0; j < arr2.length - 1 - i; j++) {
if (arr2[j] > arr2[j + 1]) {
swap(arr2, j, j + 1);
}
}
System.out.println(Arrays.toString(arr2));
}
return arr2;
}
public static void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
- 改进二,只要一轮比较没有发生交换,则可以提前结束冒泡,在本身有序的序列情况下,循环一次就行了
java
复制代码
public class Maopao2 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
int[] arr2 = {11, 23, 69, 99, 1, 3, 45, 67, 5, 234, 678, 999, 7, 123};
int[] result = maopao(arr2);
System.out.println(Arrays.toString(result));
System.out.println(System.currentTimeMillis()-start);
}
private static int[] maopao(int[] arr2) {
for (int i = 0; i < arr2.length - 1; i++) {
boolean swapBool = false; // 发生交换
for (int j = 0; j < arr2.length - 1 - i; j++) {
if (arr2[j] > arr2[j + 1]) {
swap(arr2, j, j + 1);
swapBool = true;
}
}
if (!swapBool) {
System.out.println("循环了" + i + "次");
break;
}
System.out.println(Arrays.toString(arr2));
}
return arr2;
}
public static void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
- 改进三,只需要内层循环,外层使用while(ture),用内层最后一个交换的索引来退出循环,如果最后交换的索引等于0的话说明没有交换,推出循环;
java
复制代码
public class Maopao3 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
int[] arr2 = {11, 23, 69, 99, 1, 3, 45, 67, 5, 234, 678, 7, 123,999};
int[] result = maopao(arr2);
System.out.println(Arrays.toString(result));
System.out.println(System.currentTimeMillis()-start);
}
private static int[] maopao(int[] arr2) {
int n = arr2.length - 1;
int num = 0;
while (true) {
int last = 0; // 最后一次交换的索引
for (int j = 0; j < n; j++) {
if (arr2[j] > arr2[j + 1]) {
swap(arr2, j, j + 1);
last = j;
}
}
n = last;
num++;
if (n == 0) {
break;
}
System.out.println(Arrays.toString(arr2));
}
System.out.println("循环了" + num + "次");
return arr2;
}
public static void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}