今天总结了三种时间复杂度为 O(n2)的排序算法:冒泡排序、插入排序、选择排序
插入排序和冒泡排序的时间复杂度相同,都是 O(n2),都是原地排序算法,都是稳定的排序算法,但是插入排序比冒泡所用的数据交换次数少。
选择排序是一种原地排序算法,时间复杂度都为 O(n2),选择排序是一种不稳定的排序算法。
冒泡排序:
public static void bubbleSort(int[] list) {
int len = list.length;
if (len == 0) {
return;
}
// 做多少轮排序(最多length-1轮)
for (int i = 0; i < len - 1; i++) {
boolean flag = false;
// 每一轮比较多少个
for (int j = 0; j < len - 1 - i; j++) {
if (list[j] > list[j + 1]) {
// 交换次序
int temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
flag = true;
}
}
if (!flag) {
break;
}
}
}
插入排序:
public static void insertSort(int[] list) {
int len = list.length;
// 从无序序列中取出第一个元素 (注意无序序列是从第二个元素开始的)
for (int i = 1; i < len; i++) {
int temp = list[i];
int j;
// 遍历有序序列
// 如果有序序列中的元素比临时元素大,则将有序序列中比临时元素大的元素依次后移
for (j = i - 1; j >= 0 && list[j] > temp; j--) {
list[j + 1] = list[j];
}
// 将临时元素插入到腾出的位置中
list[j + 1] = temp;
}
}
选择排序:
public static void selectionSort(int[] list) {
int len = list.length;
// 要遍历的次数(length-1次)
for (int i = 0; i < len - 1; i++) {
// 将当前下标定义为最小值下标
int min = i;
// 遍历min后面的数据
for (int j = i + 1; j <= len - 1; j++) {
// 如果有小于当前最小值的元素,将它的下标赋值给min
if (list[j] < list[min]) {
min = j;
}
}
// 如果min不等于i,说明找到真正的最小值
if (min != i) {
int temp = list[min];
list[min] = list[i];
list[i] = temp;
}
}
}
10W条测试数据排序结果:冒泡排序(25177ms)> 选择排序(8174ms)> 直接排序(1304ms)