1.冒泡排序
每一趟排序都把最大的数排到数组的最后,就像冒泡一样,一次一次往前挪动,
通过两层循环,第一层循环了数组长度-1次,第二层循环了数组长度-1再减去i
是个效率挺低的算法,时间复杂度是O(n²),是交换排序,是稳定排序。
public static void mpsort(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i; j < nums.length - 1; j++) {
if (nums[j] > nums[j + 1]) {
swap(j, j + 1, nums);
}
}
}
}
当然冒泡排序也是可以优化的,在这个算法中,有时即使数组有序了我们依旧要做很多次无用的循环。
例如数组[1,10,2,3,6]其实我们只需要一次的最外层循环我们就可以让数组有序,后几次的循环数组并没有发生交换,所以我们可以当数组在一次循环但未发生交换的时候跳出循环。下面给出优化代码:
public static void mpsort(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
boolean flag = false; //设置标志位
for (int j = i; j < nums.length - 1; j++) {
if (nums[j] > nums[j + 1]) {
flag = true;
swap(j, j + 1, nums);
}
}
if (!flag) {//判断标志位
break;
}
}
}
即使是优化后的冒牌排序,依旧不能改变其时间复杂度为O(n²)的结果,依旧是一个时间复杂度很高的排序方法,适用于小型数据的排序
2.选择排序
选择排序就是通过两层循环,第一层循环控制循环次数,第二层循环选择每次一的最小值,再把最小值放在头部,时间复杂度也是O(n²),同时也是不稳定的排序算法。
相对于冒泡排序,选择排序进行了更少的交换,我们能直观的看出来,选择排序在for循环体外进行了交换操作。故而选择排序是对冒泡排序进行的改进,只与最值进行交换。
public static void selectSort(int[] nums) {
int minIndex; //最小值的索引
int min; //最小值
for (int i = 0; i < nums.length - 1; i++) {
min = nums[i];
minIndex = i;
for (int j = i + 1; j < nums.length; j++) {
if (min > nums[j]) {
minIndex = j;
min = nums[j];
}
}
if(i != minIndex) { //如果当前数就是最小值则不进行交换
swap(i, minIndex, nums);
}
}
}