最近看到一道面试题说谈一谈几种常见的排序,猛地一下发现太久不用已经块忘了,于是今天总结总结几种常见的排序(原理和代码)。
冒泡排序:冒泡排序应该是大家印象比较深的排序方式,一说到这个排序我就想到大学时,老师说冒泡排序就像小鱼在水里吐泡泡一样慢慢变大。那冒泡排序是如何实现的呢?
实现方式:冒泡排序其实是通过每一次遍历获取此数组的最大值或者是最小值,将此值(最大值或最小值)放在头部或者尾部,然后对其余数据进行遍历获取最大或者最小值. 代码:
for (int i = 0; i < re.length - 1; i++) {
//外层循环,遍历次数
for (int j = 0; j < re.length - 1 - i; j++) {
//内层循环,升序
//内层循环一次,获取一个最大值
if (re[j] > re[j + 1]) {
int temp = re[j];
re[j] = re[j + 1];
re[j + 1] = temp;
}
}
比如数组[2,4,1,7,3,2]第一次i为0把最大值7防到了末尾[2,1,4,3,2,7] 因为7已经是最大的了所以下次就比较[2,1,4,3,2]即可.
选择排序:
实现步骤:1.将第一个值看做是最小值 2.然后和后面的比较找出整个数组最小值3.然后与本次的起始值交换 代码: 例如数组:int arr[] = {6, 5, 3, 2, 4};
//选择
for (int i = 0; i < arr.length; i++) {
//默认第一个是最小的。
int min = arr[i];
//记录最小的下标
int index = i;
//通过与后面的数据进行比较得出,最小值和下标
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]) {
min = arr[j];
index = j;
}
}
//然后将最小值与本次循环的,开始值交换
int temp = arr[i];
arr[i] = min;
arr[index] = temp;
//说明:将i前面的数据看成一个排好的队列,i后面的看成一个无序队列。每次只需要找无需的最小值,做替换
}
说明:例如第一次找出最小值2然后放入第一位然后,第二位在与前面最小的交换...
其实就是找出前面的最小值,和前面交换,使前面变为有序的,然后再次对后面操作。
插入排序:
实现步骤:受限默认从第二个数据开始比较,如果第二个数据比第一个小的话,就交换两个数。接着到第三个数和他的前一个(第二个数)比较大小,如果比前面小则插进去。否则退出(前面已经排好 没有前面小肯定比前面的所有都大). 代码:
for (int i = 1; i < arr.length; i++) {
//外层循环,从第二个开始比较
for (int j = i; j > 0; j--) {
//内存循环,与前面排好序的数据比较,如果后面的数据小于前面的则交换
if (arr[j] < arr[j - 1]) {
int temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
} else {
//如果不小于,说明插入完毕,退出内层循环
break;
}
}
}
希尔排序:
实现步骤思路:希尔排序 本质是插入排序,但是是把数组分组然后每个组内进行插入排序的,例如:步长为4那么 0,4,8 为一组,进行插入排序,然后步长减半(第一次步长通常为数组长度的一半) 代码: `> for (int i = arr.length / 2; i > 0; i /= 2) {
//i层循环控制步长
for (int j = i; j < arr.length; j++) {
//j控制无序端的起始位置
for (int k = j; k > 0 && k - i >= 0; k -= i) {
if (arr[k] < arr[k - i]) {
int temp = arr[k - i];
arr[k - i] = arr[k];
arr[k] = temp;
} else {
break;
}
}
}
//j,k为插入排序,不过步长为i
}`
为什么不直接插入排序:因为希尔排序比插入排序的比较次数少很多,如果数据比较多的话, 会很明显。