注意:7种排序算法都要会!!
七大基于比较的排序-总览
稳定性(重要)
两个相等的数据,如果经过排序后,排序算法能保证其相对位置不发生变化,则我们称该算法是具备稳定性的排序算法。
一个稳定的排序算法,可以实现为不稳定的排序,
但是一个本身就不稳定的排序,是不可以变成稳定的排序的
时间复杂度(记住平均即可,快排特殊记忆)和空间复杂度
注意:
插入排序:
时间复杂度:O(N^2) 。逆序的时候
最好的情况是O(N): 对于直接插入排序来说,最好的情况就是数据有序的时候
根据这个结论,推导出另一个结论:对于直接插入排序来说,数据越有序,越快。
希尔排序:
快速排序:
时间复杂度:
最好【每次可以均匀的分割待排序序列】:O(N*logn)
最坏:数据有序 或者逆序的情况 O(N^2)
空间复杂度:
最好:O(logn)
最坏:O(n) 单分支的一棵树
稳定性:不稳定的排序
1.冒泡排序
1.1原理
在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序
1.2实现 *
给定一个数组, 让数组升序 (降序) 排序.
算法思路
每次尝试找到当前待排序区间中最小(或最大)的元素, 放到数组最前面(或最后面).
代码示例1
// [bound, length) 构成了一个前闭后开区间, 表示已排序区间
// [0, bound)构成了一个前闭后开区间, 表示待排序区间
// 每循环一次, 就找到一个合适大小的元素, 已排序区间就增大1.
public static void main(String[] args) {
int[] arr = {
9, 5, 2, 7};
bubbleSort(arr);
System.out.println(Arrays.toString(arr));
}
private static void bubbleSort(int[] arr) {
for (int bound = arr.length; bound > 0; bound--) {
for (int cur = 0; cur < bound - 1; cur++) {
if (arr[cur] > arr[cur + 1]) {
swap(arr,cur,cur+1);
}
}
}
}
// 执行结果
[2, 5, 7, 9]
或者:
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
boolean isSorted = true;
for (int j = 0; j < array.length - i - 1; j++) {
// 相等不交换,保证稳定性
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
isSorted = false;
}
}
if (isSorted) {
break;
}
}
}
public static void swap(int[] array,int i,int j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
1.3性能分析
稳定性:稳定
2.插入排序
2.1直接插入排序-原理
整个区间被分为
1.有序区间
2.无序区间
每次选择无序区间的第一个元素,在有序区间内选择合适的位置插入
2.2实现 *
public static void insertSort(int[] array) {
for (int i = 1; i < array.length; i++) {
int tmp = array[i];
int j = i-1;
for (; j >= 0 ; j--) {
if(array[j] > tmp) {
array[j+1] = array[j];
}else {
//array[j+1] = tmp; 只要j回退的时候,遇到了 比tmp小的元素就结束这次的比较
break;
}
}
//j回退到了 小于0 的地方
array[j+1] = tmp;
}
}
2.3性能分析
有序的情况下,时间复杂度是O(n)
稳定性:稳定
插入排序,初始数据越接近有序,时间效率越高。
3.选择排序
3.1直接选择排序-原理
每一次从无序区间选出最大(或最小)的一个元素,存放在无序区间的最后(或最前),直到全部待排序的数据元素
排完。