写在开头
最近读了一些Spring的源码,深刻理解了基本功的重要性。遂重新拿起了数据结构和算法来重新学习一遍,刷到排序时,对三个复杂度的排序算法又多了一些新的认识,写下这篇文章,权当做是笔记了。
冒泡排序
首先,日常开发中,涉及到排序时,或者使用
Arrays.sort()
或者使用插入排序,对于冒泡排序用的相对来讲要少些,但还是有必要了解一下的。
简介
冒泡排序是针对相邻两个元素之间的大小比较,并不会产生额外的空间开销(只会用到一个临时变量用于交换),是典型的原地排序,且对于值相同的元素,不会进行位置上的交换,这一点就是典型的稳定排序。
代码
private static int[] sort(int[] array) {
int n = array.length;
// 使用冒泡排序:相邻元素进行比较大小
for (int i = 0; i < n; i++) {
// 相邻元素之间的俩俩比较
for (int j = 0; j < n - i - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
插入排序
简介
这个排序很多人应该都不陌生,最开始工作写代码,在涉及排序时应该首先想到的就是这个插排了!(我是这样的,直到知道了Arrays.sort()!)
与冒泡排序一样,他的时间复杂度也是:,同样是原地排序,也是稳定排序。
插入排序将待排序数组分为有序数组和无序数组两部分,起始排序以第一个元素为有序数组,其后均为无序,每次从无序数组中获取一个元素与有序数组做比较,并插入到有序数组中的合适位置。
代码
private static int[] doSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] > array[j]) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
return array;
}
选择排序
简介
与插入排序一样,选择排序也将数组分成有序和无序两部分,但是选择排序每次是从未排序区间中获取最小的元素并放到有序数组的最后。
代码
private static int[] doSort(int[] array) {
// 选择排序:默认第一个元素为初始有序数组,与其后元素最比较,找出最小值放到第一个
for (int i = 0; i < array.length; i++) {
// 默认第一个为最小值
int min = i;
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[min]) {
min = j;
}
}
if (min != i) {
// 执行交换
int temp = array[min];
array[min] = array[i];
array[i] = temp;
}
}
return array;
}
总结
三个排序算法的时间复杂度均为,因此在对长度有限的数组进行排序时,可以作为首选。
至于量为多大,建议参阅Java中的Arrays.sort()的源码,其中对于选择哪一种排序算法时,有写上阈值的,阈值部分的源码我贴过来了,注释或者变量的命名应该就能看出来了。
/**
* The maximum number of runs in merge sort.
*/
private static final int MAX_RUN_COUNT = 67;
/**
* The maximum length of run in merge sort.
*/
private static final int MAX_RUN_LENGTH = 33;
/**
* If the length of an array to be sorted is less than this
* constant, Quicksort is used in preference to merge sort.
*/
private static final int QUICKSORT_THRESHOLD = 286;
/**
* If the length of an array to be sorted is less than this
* constant, insertion sort is used in preference to Quicksort.
*/
private static final int INSERTION_SORT_THRESHOLD = 47;
/**
* If the length of a byte array to be sorted is greater than this
* constant, counting sort is used in preference to insertion sort.
*/
private static final int COUNTING_SORT_THRESHOLD_FOR_BYTE = 29;
/**
* If the length of a short or char array to be sorted is greater
* than this constant, counting sort is used in preference to Quicksort.
*/
private static final int COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR = 3200;