最近重新开始学Java基础,看到了选择排序。因为以前基本只用冒泡,Java数组的话直接 Arrays.sort()
,所以对这两种排序方法的理解有些模糊,所以更深入的了解了一下。
- 为理解方便,在这里我所举的例子都以从小到大的顺序排序。
冒泡排序(Bubble Sort)##
- 原理:每次比较两个相邻的元素,将值大的元素交换至右端。
- 思路:冒泡排序有两层循环,外层循环控制循环次数,循环的次数是
array.lenth-1
。如果不减一,当循环到数组最后一位时,要与它右边的数进行比较,会发现超出数组长度,即抛出ArrayIndexOutOfBoundsException
异常。内层循环控制每一趟排序多少次,如果发现前面大于后面,则交换。 - 源码:
public class BubbleSort {
public static void main(String[] args) {
int[] array = {3,4,7,9,1};
//外层循环控制循环次数
for (int i = 0; i < array.length-1; i++) {
//内层循环控制每一趟排序多少次
for (int j = 0; j < array.length-i-1; j++) {
//升序--如果前面大于后面则交换
if (array[j] > array[j+1]){
//采用两数异或作交换,无须引入另外的变量,更高效
array[j] = array[j] ^ array[j+1];
array[j+1] = array[j] ^ array[j+1];
array[j] = array[j] ^ array[j+1];
}
}
}
//foreach循环输出数组
for (int obj:a)
System.out.print(obj + " ");
}
}
- 平均时间复杂度:O(N*N)
选择排序(Select Sort)
- 原理:每次循环找到最小值交换到数组左端
- 思路:选择排序同样有两层循环。外层循环与冒泡排序一样是控制循环次数,这里有一个自定义的最小值元素的下标,在内层循环中通过下标进行比较,如果发现比自定义最小值元素下标还要小的值,则将该值的下标赋值给自定义的最小值元素下标。在一次内层循环结束后,将最小值元素交换至数组左端。
- 源码:
public class SelectSort {
public static void main(String[] args) {
int[] a = {3,4,7,9,1};
int min;//最小值
int index = 0;//最小值的下标
//外层循环控制循环次数
for (int i = 0; i < a.length-1; i++) {
min = a[i];//假设最小值是i
index = i;
//内层循环 用假设的最小值与它之后的数进行比较
for (int j = i+1; j < a.length; j++) {
if (min > a[j]) {
min = a[j];
index = j;
}
}
//退出内层循环后, 如果index的值发生变化,将最小值与i进行交换
if (i != index){
a[i] = a[i] ^ a[index];
a[index] = a[i] ^ a[index];
a[i] = a[i] ^ a[index];
}
}
for (int obj:a)
System.out.print(obj + " ");
}
}
- 时间复杂度O(N*N)
异同
- 时间复杂度相同,都为O(N*N)
- 在内层循环中,冒泡排序的交换操作一般要多于选择排序,选择排序换位操作为O(n),而冒泡排序为O(n^2/2),所以综合来讲,选择排序的时间效率要高于冒泡排序。