基础排序算法
1、冒泡排序
冒泡排序,顾名思义,按泡泡一样上浮起来。每一次比较2个相邻的数字,进行交换,交换到最后,便完全了一个数字的排序。进行N次比较,就完成了N个数字的排序。
例如:
2 4 8 3 9 1 按从小到大排序

for (int i = 0; i < n; ++i) {
// 提前退出冒泡循环,当在一次冒泡过程中,都没有一个数据发送交互,则可以提前退出循环,因为数据已经排好序了,节省了多余的循环
boolean flag = false;
for (int j = 0; j < n - i - 1; ++j) {
if (a[j] > a[j+1]) {
// 按顺序进行交换
int tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
// 表示有数据交换
flag = true;
}
}
if (!flag) break; // 没有数据交换,提前退出
}
从代码中可以看出,冒泡排序是一种稳定的排序算法。稳定的判断在于,当2数相同时,排序前后,2数的顺序是否会发生变化
2、选择排序
选择排序:在每一次排序中,查到最小(大)元素,按序排列。最后排列出来的就是排序的结果。
git图如下,转自其他网站

// 总共要经过 N-1 轮比较
for (int i = 0; i < arr.length - 1; i++) {
int min = i;
// 每轮需要比较的次数 N-i
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
// 记录目前能找到的最小值元素的下标
min = j;
}
}
// 将找到的最小值和i位置所在的值进行交换
if (i != min) {
int tmp = arr[i];
arr[i] = arr[min];
arr[min] = tmp;
}
}
当存在2个相同的数时,2个数的顺序在排序中就无法保持原样,故不稳定
3、插入排序
把数列分为2个区域,一个是已排序区域,一个是未排序区域。每次从未排序的区域里面找一个元素,插入已排序区中 如下图

java代码如下
for (int i = 1; i < n; ++i) {
int value = a[i];
int j = i - 1;
// 查找插入的位置
for (; j >= 0; --j) {
if (a[j] > value) {
// 数据整体向后移动
a[j+1] = a[j];
} else {
break;
}
}
// 插入数据
a[j+1] = value;
}
当相同的元素出现时,保持原来的顺序不变,插入排序是稳定的排序算法
4、快速排序
单纯从时间复杂度来讲,快速排序最好。
选择一个基准数,把数字按这个基准数分为2部分,一部分大于基准数,一部分都小于基准数。再从2部分中,分布选择一个基准数,各自进行上诉操作。以此类推,直到不能再分。
例如:
4 2 8 3 9 1 按从小到大排序
第一次的基准数设置为 4
{ 3 2 1 } 4 { 9 8 }
第二次分别对 {321} 和{98} 进行排序
321 选择 3 {1 2} 3
98 选择 8 {8,9} 结束,因为无法再分
第三次 对{1 2} 排序
...
最后得到
123489 序列
java代码如下
private static void quickSort(int[] arr, int low, int high) {
if(low > high){
return;
}
int temp = arr[low];
int i = low;
int j = high;
while (i < j){
while(temp <= arr[j] && i<j){
j--;
}
while(temp >= arr[i] && i<j){
i++;
}
if(i <j){
int t = arr[j];
arr[j] = arr[i];
arr[i] =t;
}
}
arr[low] =arr[i];
arr[i] = temp;
quickSort(arr,low,j-1);
quickSort(arr,j+1,high);
}
在相同元素的情况下,此时也无法保证稳定性。选择基准数的不同,不一定还能保持原有的顺序。