1.介绍
常用的排序算法主要有冒泡排序,选择排序,插入排序,希尔排序,堆排序,归并排序,快速排序,桶排序等。
2.稳定性
稳定的排序算法:冒泡排序,插入排序;
不稳定的排序算法:选择排序,希尔排序,堆排序,归并排序,快速排序。
3.排序算法的实现
3.1冒泡排序
冒泡排序的时间复杂度为O(n*n),空间复杂度为O(1),在数据有序的时候时间复杂度可以达到O(n)。
适用的情景为数据量量不大,对稳定性有要求,且数据基本有序的情况下。其常见实现方式如下:
public int[] sort_bubble1(int[] array) {
int len = array.length;
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
if (array[i] > array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
return array;
}
3.2选择排序
选择排序的时间复杂度为O(n*n),空间复杂度为O(1),由于每次选出待排序数据中的最小值(增序)或最大值(降序)插入到当前的有序队列中,相对于冒泡排序减少了交换的次数。
当数据量不大,且对稳定性没有要求的时候,适用于选择排序。其代码如下:
public int[] sort_simple(int[] array) {
int len = array.length;
for (int i = 0; i < len - 1; i++) {
int min = i;
for (int j = i + 1; j < len; j++) {
if (array[min] > array[j])
min = j;
}
if (min != i) {
int temp = array[i];
array[i] = array[min];
array[min] = temp;
}
}
return array;
}
3.3插入排序
插入排序的时间复杂度为O(n*n),空间复杂度为O(1),最好的情况下即当数据有序时可以达到O(n)的时间复杂度,其排序的思想非常类似于我们打扑克牌的时对手里的牌进行排序的过程,选出一个值,将其插入在合适的排序位置。
适用于数据量不大,对算法的稳定性有要求,且数据局部或者整体有序的情况。其代码如下:
public int[] sort_insert(int[] array) {
int len = array.length;
for (int i = 1; i < len; i++) {
if (array[i] < array[i - 1]) {
int temp = array[i];
int j = i - 1;
for (; j >= 0 && array[j] > temp; j--) { // 这里逻辑与判断的顺序一定不可以颠倒
array[j + 1] = array[j];
}
array[j + 1] = temp;
}
}
return array;
}
3.4快速排序
快速排序算发的时间复杂度为O(nlogn),由于快速排序使用递归的方式实现,因此空间复杂度为O(nlogn)到O(n)之间。快速排序的思想是设置一个数据作为分割线,将小于它的数据交换至其左侧,大于它的数据交换到它的右侧(当数据增序排列的时候)。
由于快速排序的原理,常用于查找一组中前k大的数据。其代码如下:
private int partion(int[] array, int low, int high) {
System.out.println("low is:" + low + ";high is:" + high);
int mid = array[low];
while (low < high) {
while (low < high && array[high] >= mid)
high--;
// int temp = array[high];
// array[high] = array[low];
// array[low] = temp;
array[low] = array[high];
while (low < high && array[low] <= mid)
low++;
// temp = array[high];
// array[high] = array[low];
// array[low] = temp;
array[high] = array[low];
}
array[low] = mid;
System.out.println("array is:" + Arrays.toString(array));
System.out.println("low is:" + low + ";high is:" + high + ";index is:" + low);
return low;
}
private void sort(int[] array, int low, int high) {
// System.out.println(low+"---"+high);
if (low < high) {
int p = partion(array, low, high);
// System.out.println(p);
// System.out.println(Arrays.toString(array));
sort(array, low, p - 1);
sort(array, p + 1, high);
}
}
public int[] sort_quick(int[] array) {
sort(array, 0, array.length - 1);
return array;
}
3.5堆排序
堆排序的时间复杂度为O(nlog),空间复杂度为O(1)。实现原理是根据大顶堆或小顶堆得数据结构原理,对待排序数据进行调整,最终达到整体有序的效果,其代码如下:
private void heap_adjust(int[] array, int s, int len) {
int temp = array[s];
for (int i = 2 * s + 1; i < len; i = i * 2 + 1) {
if (i < len - 1 && array[i] < array[i + 1])
i++;
if (array[i] <= temp)
break;
array[s] = array[i];
s = i;
}
array[s] = temp;
}
public int[] sort_heap(int[] array) {
int len = array.length;
for (int i = (len - 1 - 1) / 2; i >= 0; i--) {
heap_adjust(array, i, len);
}
for (int j = len - 1; j > 0; j--) {
int temp = array[j];
array[j] = array[0];
array[0] = temp;
heap_adjust(array, 0, j);
}
return array;
}