前言
排序算法事很重要的算法之一,几乎是Java的面试必问题了,在此通过几篇博文,总结一下几种常见的排序算法。当然这只是其中的几个。
排序算法可以分为内部排序和外部排序。
- 外部排序通常是读数据量很大的数据进行排序,且因为需要排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。
- 内部排序需要排序的数据量相对较小。是将需要排序的数据记录在内存中进行排序。
博文链接:(点击排序名称可看到不同排序的博文。不断更新中…)
常见的内部排序算法有:冒泡排序、选择排序、插入排序、希尔排序、快速排序
几种排序的比较:
排序算法 | 时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|
冒泡排序 | O(n2) | O(1) | 稳定 |
选择排序 | O(n2) | O(1) | 不稳定 |
插入排序 | O(n2) | O(1) | 稳定 |
快速排序 | O(n logn) | O(log n) | 不稳定 |
归并排序 | O(n logn) | O(n) | 稳定 |
希尔排序 | O(n logn) | O(1) | 稳定 |
插入排序
-
排序方式
以从小到排序为例:
默认从第二个开始比较。如果第二个数字比第一个数字小,则插到第一个数字前面,再用第三个数字比较,
如果第三个数字比第二个数字小,插入到第二个前面,然后再个第一个数字比较,如果比第一个数字小,插入到第一个数字前面。如果比第一个数字大,则保持不变,退出本次循环
…
依次执行上面的循环比较,直到将最后一个数字插入到相应的位置为止。 -
排序讲解
例如对: 5 4 2 7 3 进行从小到大排序。具体的过程为:
第一次外循环:
用第二个数字4作为第一轮的开始,向前插入- 第一次内循环:第二个数字和第一个数字比较,于是4和5相比,4小,将4插入到5的前面,顺序变为:4 5 2 7 3
第二次外循环:
用第三个数字2作为第二轮的开始,向前插入- 第一次内循环:第三个数字和第二个数字比较,于是2和5相比,2小,将2插入到5的前面,顺序变为:4 2 5 7 3
- 第二次内循环:第二个数字和第一个数字比较,于是2和4相比,2小,交换2和4的顺序,顺序变为:2 4 5 7 3
第三次外循环:
用第四个数字7作为第三轮的开始,向前插入- 第一次内循环:第四个数字和第三个数字比较,于是7和5相比,5小,不需要交换顺序,退出本次循环,当前顺序为:2 4 5 7 3
第四次外循环:
用第五个数字3作为第四轮的开始,向前插入。- 第一次内循环:第五个数字和第四个数字比较,于是3和7相比,3小,将3插入到7的前面,顺序变为:2 4 5 3 7
- 第二次内循环:第四个数字和第三个数字比较,于是3和5相比,3小,将3插入到7的前面,顺序变为:2 4 3 5 7
- 第三次内循环:第三个数字和第二个数字比较,于是3和4相比,3小,将3插入到4的前面,顺序变为:2 3 4 5 7
- 第四次内循环:第二个数字和第一个数字比较,于是3和2相比,2小,不需要交换顺序,退出本次循环,当前顺序为:2 4 5 7 3
-
代码实现
/**
* 插入排序
* @param arr 需要排序的数组
*/
public static void insertSort(int arr[]){
//第一层循环,默认从第二个开始比较
for (int i = 1; i < arr.length; i++) {
// 内层循环
for (int j = i ; j > 0; j--) {
//如果后一个数据小于前一个,就向前插入
if(arr[j-1] > arr[j]){
int tmp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = tmp;
}else {
// 否则退出本层循环
break;
}
}
}
}