普通冒泡:
/**
* @author jyroy
* 冒泡排序常规版
*/
public class BubbleSortNormal {
public static void main(String[] args) {
int[] list = {3,4,1,5,2};
int temp = 0; // 开辟一个临时空间, 存放交换的中间值
// 要遍历的次数
for (int i = 0; i < list.length-1; i++) {
System.out.format("第 %d 遍:\n", i+1);
//依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上
for (int j = 0; j < list.length-1-i; j++) {
// 比较相邻的元素,如果前面的数小于后面的数,就交换
if (list[j] < list[j+1]) {
temp = list[j+1];
list[j+1] = list[j];
list[j] = temp;
}
System.out.format("第 %d 遍的第%d 次交换:", i+1,j+1);
for(int count:list) {
System.out.print(count);
}
System.out.println("");
}
System.out.format("第 %d 遍最终结果:", i+1);
for(int count:list) {
System.out.print(count);
}
System.out.println("\n#########################");
}
}
}
暴力循环,每趟选出最大或最小的值,哪怕已经有序,还是进行比较
冒泡进化版
/**
* @author jyroy
* 冒泡排序优化第一版
*/
public class BubbleSoerOpt1 {
public static void main(String[] args) {
int[] list = {5,4,3,1,2};
int temp = 0; // 开辟一个临时空间, 存放交换的中间值
// 要遍历的次数
for (int i = 0; i < list.length-1; i++) {
int flag = 1; //设置一个标志位
//依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上
for (int j = 0; j < list.length-1-i; j++) {
// 比较相邻的元素,如果前面的数小于后面的数,交换
if (list[j] < list[j+1]) {
temp = list[j+1];
list[j+1] = list[j];
list[j] = temp;
flag = 0; //发生交换,标志位置0
}
}
System.out.format("第 %d 遍最终结果:", i+1);
for(int count:list) {
System.out.print(count);
}
System.out.println("");
if (flag == 1) {//如果没有交换过元素,则已经有序
return;
}
}
}
}
使用变量来确认上一次循环是否发生了交换,若发生了交换,说明有必要进行下一轮比较,若没有发生交换,表示序列已经有序,就跳出循环,省掉多余比较。
冒泡超级进化版
/**
* @author jyroy
* 冒泡排序优化第二版
*/
public class BubbleSoerOpt2 {
public static void main(String[] args) {
int[] list = {6,4,7,5,1,3,2};
int len = list.length-1;
int temp = 0; // 开辟一个临时空间, 存放交换的中间值
int tempPostion = 0; // 记录最后一次交换的位置
// 要遍历的次数
for (int i = 0; i < list.length-1; i++) {
int flag = 1; //设置一个标志位
//依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上
for (int j = 0; j < len; j++) {
// 比较相邻的元素,如果前面的数小于后面的数,交换
if (list[j] < list[j+1]) {
temp = list[j+1];
list[j+1] = list[j];
list[j] = temp;
flag = 0; //发生交换,标志位置0
tempPostion = j; //记录交换的位置
}
System.out.format("第 %d 遍第%d 趟结果:", i+1, j+1);
for(int count:list) {
System.out.print(count);
}
System.out.println("");
}
len = tempPostion; //把最后一次交换的位置给len,来缩减内循环的次数
System.out.format("第 %d 遍最终结果:", i+1);
for(int count:list) {
System.out.print(count);
}
System.out.println("");
if (flag == 1) {//如果没有交换过元素,则已经有序
return;
}
}
}
}
增设变量来确认上一次最后进行交换的位置,说明,这个位置之后的值已经有序,下次比较可以只比较改位置前边的数据,进一步省掉不需要的交换。
总结
稳定性:
稳定,只比较大小,相等的值不会被交换位置
时间复杂度:
最坏运行次数 (1+N)xN/2 次
即是O(N2 )的复杂度
最好运行次数:n次
即是O(n)的复杂度
所以平均时间复杂度:
O(N2)
空间复杂度:
只需要一个用于交换的空间,
即是O(1)