【算法】冒泡排序
2019-11-26 本文已影响0人
天空若放晴
基本思想:
把数组中相邻的元素两两比较,根据大小来交换元素位置。第一轮两两交换之后,可以得出最大值会在最右边;接着重复上面的动作,进行下一轮交换。知道所有元素从小到大排序位置。
-
BubbleSort 0.1 version
public static void bubbleSort1(int arr[]) {
int tmp = 0;
//开始遍历数组 进行两两比较
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
//相邻元素两两比较 把大的放到右边。
if (arr[j]>arr[j+1]) {
tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
关于优化
在冒泡排序的后期排序的过程中,其实数组中的数据可能已经处于有序的状态,如果此时继续使用基础版本的排序会大大降低程序的性能,耗费不必要的时间。
我们可以在冒泡排序交换前设置一个布尔型的变量来表示数组是否有序,如果进行交换操作即数组处于无序状态;如果没有进行数据交换即数组已经有序,此时可以跳出循环,结束程序。
-
BubbleSort 0.2 version
public static void bubbleSort2(int arr[]) {
int tmp = 0;
//开始遍历数组 进行两两比较
for (int i = 0; i < arr.length-1; i++) {
//有序标记 每一轮开始都为true
boolean isSorted = true;
for (int j = 0; j < arr.length-i-1; j++) {
//相邻元素两两比较 把大的放到右边。
if (arr[j]>arr[j+1]) {
tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
//有交换 即无序
isSorted = false;
}
}
//如果数组是有序的 则跳出循环
if (isSorted) {
break;
}
}
}
有一种情况,如果在一开始排序的时候数组已经呈现半有序的状态,程序按基本版的操作一定是多做工的,所以我们可以记录下每一轮最后交换的位置,这个位置就是数组有序和无序的分界。这样下一轮的排序就可以在这个临界点结束。
-
BubbleSort 0.3 version
//避免半有序的数组多次循环 如{3,2,4,1,5,6,7,8} 。
public static void bubbleSort3(int arr[]) {
int tmp = 0;
//开始遍历数组 进行两两比较
for (int i = 0; i < arr.length-1; i++) {
//有序标记 每一轮开始都为true
boolean isSorted = true;
//设置无序边界 每次比较只需比到这里为止
int sortBorder = arr.length-1;//初始值为最右
for (int j = 0; j < sortBorder; j++) {
//相邻元素两两比较 把大的放到右边。
if (arr[j]>arr[j+1]) {
tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
//有交换 即无序
isSorted = false;
//记录最后一次交换的位置
sortBorder = j;
}
}
//如果数组是有序的 则跳出循环
if (isSorted) {
break;
}
}
}
总结
上面就是冒泡排序及其优化之后的代码,接下来学习的是选择排序。