说明
- 稳定性:稳定
- 时间复杂度:最好-O(n);最坏O(n^2);平均O(n^2);
- 空间复杂度:O(1)
- 使用场景:数据规模小的场景
- 算法思想:比较相邻的两个元素,将较小的数交换到左端,直到序列有序。
- 实现说明:包含两层循环,每次外层循环冒出最大的一个数到length-1-i的位置,内存循环,每次比较相邻两个数,将较大数换到后面直到length-i-1位置。
- 优化说明:包括两种优化,优化外层循环和优化内层循环。
1.代码实现
public static void main(String[] args) {
//产生0-9随机序列
final int MAX_SIZE = 10;
int[] list = new int[MAX_SIZE];
System.out.println("待排序列:");
for(int i = 0;i<list.length;i++) {
list[i] = (int)(Math.random()*MAX_SIZE);
System.out.print(list[i] + " ");
}
//排序
//表示每次循环都冒出一个最小(大)的数
for (int i = 0; i < list.length; i++) {
//将最大的数冒到右端(两两交换)
for(int j = 0;j<list.length-i-1;j++) {
if (list[j] > list[j+1]) {
int temp = list[j];
list[j] = list[j+1];
list[j+1] = temp;
}
}
}
//打印有序序列
System.out.println("\n有序序列");
for (int i = 0; i < list.length; i++) {
System.out.print(list[i]+" ");
}
}
2.优化外层循环
可以知道,如果某次循环没有进行数据交换,那么序列已经有序,后面的循环不需要再执行。因此可以用一个变量来记录是否发生了交换。
public static void main(String[] args) {
boolean flag = true; //表示是否继续循环变量
//产生0-9随机序列
final int MAX_SIZE = 10;
int[] list = new int[MAX_SIZE];
System.out.println("待排序列:");
for(int i = 0;i<list.length;i++) {
list[i] = (int)(Math.random()*MAX_SIZE);
System.out.print(list[i] + " ");
}
//排序
//表示每次循环都找出一个最小(大)的数
for (int i = 0; i < list.length && flag; i++) {
flag = false;
//将最大的数冒到右端(两两交换)
for(int j = 0; j <list.length - i - 1;j++) {
if (list[j] > list[j+1]) {
int temp = list[j];
list[j] = list[j+1];
list[j+1] = temp;
//如果进行了交换则继续,该方法需要多进行一次无用循环,用来判断是否有序
flag = true;
}
}
}
//打印有序序列
System.out.println("\n有序序列");
for (int i = 0; i < list.length; i++) {
System.out.print(list[i]+" ");
}
}
3.优化内层循环
可以知道某次循环交换的最后一次的后面的值是有序的,因此我们可以记录这个位置,在后面的循环我们只用交换到这个位置即可。
public static void main(String[] args) {
// 产生随机序列
final int MAX_SIZE = 10;
int[] list = new int[MAX_SIZE];
Random random = new Random();
System.out.println("待排序列:");
for (int i = 0; i < list.length; i++) {
list[i] = random.nextInt(MAX_SIZE);
System.out.print(list[i] + " ");
}
// 排序
// 记录每次的last值
int pos = list.length - 1;
// 保存上一次冒泡的last值
int last;
for (int i = 0; i < list.length; i++) {
last = pos;
// 根据上次的last值其后的数不需要交换
for (int j = 0; j < last; j++) {
if (list[j] > list[j + 1]) {
int temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
pos = j;
}
}
}
// 打印有序序列
System.out.println("\n有序序列");
for (int i = 0; i < list.length; i++) {
System.out.print(list[i] + " ");
}
}
4.两种优化方式结合
public static void main(String[] args) {
// 产生随机序列
final int MAX_SIZE = 10;
int[] list = new int[MAX_SIZE];
Random random = new Random();
System.out.println("待排序列:");
for (int i = 0; i < list.length; i++) {
list[i] = random.nextInt(MAX_SIZE);
System.out.print(list[i] + " ");
}
// 排序
// 记录每次的last值
int pos = list.length - 1;
// 保存上一次冒泡的last值
int last;
// 记录是否发生了交换
boolean flag = true;
for (int i = 0; i < list.length && flag; i++) {
last = pos;
flag = false;
for (int j = 0; j < last; j++) {
if (list[j] > list[j + 1]) {
int temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
pos = j;
flag = true;
}
}
}
// 打印有序序列
System.out.println("\n有序序列");
for (int i = 0; i < list.length; i++) {
System.out.print(list[i] + " ");
}
}
}