自己整理不算转发也不算原创
原始的冒泡排序算法的每一轮要遍历所有的元素,轮转次数和元素数量相当,时间复杂度是O(N^2)
1)原始的冒泡排序就算排序几轮过后后半部分已经有序,原机制还是会从头一直继续执行,执行无用功。
所以优化办法之一就是判断数组是否已经有序,并且做出标记,剩下几轮就不必在执行。进行了交换说明无序,没有进行交换则说明有序。
public class Test {
private static void sort(int array[]) {
int temp = 0;
for(int i=0;i< array.length-1;i++) {
boolean isSorted = true;//放到这个位置每轮进行重新有序位置点
for(int j=0;j<array.length-i-1;j++) {
if(array[j]>array[j+1]) {
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
isSorted = false;//标志说明不是有序的
}
}
if(isSorted) {
break;
}
}
}
public static void main(String[] args) {
int a[] = {9,4,3,7,8,5,2,6,1};
sort(a);
System.out.println(Arrays.toString(a));
}
}
2) 第一轮排序最后一个是有序,第二轮排序最后两个是有序的,以此类推可视化规律-》(有序区的长度和排序的轮数是相等的)这个位置点之前的也不一定没有顺序,可能未排序之前就具有部分顺序,有序区范围大于排序的轮数;也就是说还是要找到最后一次进行调换的位置,那个点就是其之后的数据都是有序的。
public class Test {
private static void sort(int array[]) {
int temp = 0;
//记录最后一次交换的位置
int lastIndex = 0;
//无序数列的边界,每次比较只需要比到这里为止
int sortBorder = array.length - 1;
for(int i = 0; i < array.length; i++) {
//有序标记,每一轮的初始是true
boolean isSorted = true;
for(int j = 0; j < sortBorder; j++) {
if(array[j] > array[j+1]) {
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
//把无序数列的边界更新为最后一次交换元素的位置
lastIndex = j;
}
}
sortBorder = lastIndex;
if(isSorted){
break;
}
}
}
public static void main(String[] args) {
int a[] = {7,8,5,2,9,4,3,6,1};
sort(a);
System.out.println(Arrays.toString(a));
}
}