一些定义
1.排序算法的内存消耗(空间复杂度)
算法的内存消耗可以通过空间复杂度来衡量,简单来说就是这个排序要占用多少内存.这里引入一个概念-原地排序,特指空间复杂度为O(1)的排序算法,简单理解,就是不需要额外花费空间(原地:原来多大就多大)的算法.(在接下来的例子中,我会详细解释如何判断是否为原地排序)
2.排序算法的稳定性
稳定性。这个概念是说,如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。
简单举个例子吼: 比如7 9 6(1号) 6(2号) 8 10 排序后如果为 6(一号) 6(二号) 7 8 9 10
则为稳定排序 如果为6(二号) 6(一号) 7 8 9 10则为不稳定排序.
这里有一个小小tips: 笔者在之前理解的时候,认为不稳定排序为相等排序一会先一会后,但实际上,只要相等元素之间原有的先后顺序改变,就是不稳定结构,哪怕一直是后来者居前 也是不稳定的
tips2:大家可能会想:"啊!都是相同的数据了!你还排个锤子排!你给我去spa!",这里举一个小小的例子:订单系统,两名顾客下单的是同一种商品,但是他们的时间总得有个先来后到对吧
冒泡排序
首先是大家喜闻乐见的冒泡排序....
冒泡排序会操作相邻的两个数据。每次操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。
举个栗子
一组数据为 8,7,5,9,6
进行一次"冒泡":(要我说他就不叫冒泡 叫沉底 每次把一个最沉(大)的元素沉到海底)
8>7 -> 7 8 5 9 6
8>5 -> 7 5 8 9 6
8<9 -> 7 5 8 9 6
9>6 -> 7 5 8 6 9
然后在按照这个规则再进行冒泡
代码示例
public static void bubbleSort(int[] a, int n){
for(int i = 0;i<=n-1;i++){
for(int j = 0;j<=n-i-2;j++){
if(a[j]>a[j+1]){
int tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
}
}
}
}
值得一提的是 冒泡排序是有优化的可能的 如果是 1 3 5 2 4 6这组数据冒泡排序
第一次冒泡1 3 2 4 5 6
第二次冒泡1 2 3 4 5 6
只需要两次冒泡就已经排序好了,但是按照程序运行的话要运行六次才会结束
所以我们对其进行优化,如果没有元素交换 则为已经排序完毕
public static void bubbleSort(int[] a, int n){
for(int i = 0;i<=n-1;i++){
boolean jud = true;
for(int j = 0;j<=n-i-2;j++){
if(a[j]>a[j+1]){
int tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
jud = false;
}
}
if(jud){
break;
}
}
}
插入排序
借用一下王争老师的图
插入排序逻辑如下
public static void insertsort(int [] arr) {
if(arr.length<=1) {
return;
}
for(int i = 1;i<arr.length;i++) {
int value = arr[i];//预选保存当前元素
int j = i-1;
for(;j>=0;j--) {//移动元素 腾出要插的位置 如果后面的大于前面的逐个移动 如果不大于直接跳出循环
if(arr[j]>value) {
arr[j+1] = arr[j];
}else {
break;
}
}
arr[j+1] = value;//插入元素 在j+1处空出的地方
}
}
public static void main(String[] args) {
int [] arr = {1,3,5,7,9,2,4,6,8,10};
insertsort(arr);
System.out.println(Arrays.toString(arr));
}
选择排序
逻辑最简单
0 ~ N-1 找到最小值,在哪,放到0位置上
1 ~ n-1 找到最小值,在哪,放到1 位置上
2 ~ n-1 找到最小值,在哪,放到2 位置上
以此类推
public static void selectionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) { // i ~ N-1 上找最小值的下标
minIndex = arr[j] < arr[minIndex] ? j : minIndex;
}
swap(arr, i, minIndex);
}
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void main(String[] args) {
int [] arr = {1,3,5,7,9,2,4,6,8,10};
selectionSort(arr);
System.out.println(Arrays.toString(arr));
}