插入排序
介绍
插入排序(Insertion Sort)是一种简单直观的排序算法。
它的工作方式类似于我们玩扑克牌时整理手牌的过程。我们开始时左手拿着一张牌,每次从桌上拿起一张新的牌,并与左手中的每张牌从右到左进行比较,直到找到合适的位置插入这张新牌,然后重复这个过程直到桌上所有的牌都被拿完并插入到左手中的正确位置。
插入排序也是这样,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
原理
让我们通过一个简单的例子来理解插入排序的原理。假设我们有一个数组 [3, 5, 4, 1, 6, 2]
,我们想要将它按照从小到大的顺序排序。
刚开始,我们从数组的第二个元素开始排序,将第一个元素 3
做为已排序部分:
因为 5 > 3
所以 5
的位置不需要改变:
此时,待排序元素为 4
,因为 4 > 3
并且 4 < 5
,所以 3
之后的有序部分整体后移一个位置,再将 4
填入 3
的后一个位置:
此时,待排序元素为 1
,因为 1 < 3
,也就是比有序部分中的所有元素都小,所以有序部分中的所有元素都向后移动一个位置,再将 1
填入 3
的前一个位置:
此时,待排序元素为 6
,比有序部分中的所有元素都大,因此元素 6
的位置不变:
此时,待排序元素为 2
,因为 2 > 1
且 2 < 3
,所以 1
之后的有序部分整体后移一个位置,再将 2
填入 1
的后一个位置:
至此,排序完成!
排序的动态效果图如下:
alt=“插入排序” style=“zoom: 80%;”
代码
/**
* 插入排序的实现
*
* @author 孤诣
*/
public class InsertionSort {
public static void main(String[] args) {
// 数据准备
int[] dataArray = {7, 0, 9, 5, 6, 8, 4, 3, 1, 2};
System.out.println("排序前: " + Arrays.toString(dataArray));
// 排序
insertionSort(dataArray);
System.out.println("排序后: " + Arrays.toString(dataArray));
}
/**
* 插入排序算法的实现
*
* @param source 源数组
*/
public static void insertionSort(int[] source) {
if (source == null) {
return;
}
int length = source.length;
// 从数组第二个元素开始遍历
for (int i = 1; i < length; i++) {
int current = source[i]; // 当前待排序元素
int j = i - 1; // 有序部分最大元素的下标
// 找到合适的插入位置
while (j >= 0 && source[j] > current) {
source[j + 1] = source[j]; // 比当前待排序元素大的有序元素后移
j--;
}
// 将当前待排序元素插入到正确位置(此时 j 就是正确位置的下标)
source[j + 1] = current;
}
}
}
评估
时间复杂度:
- 最好情况:
O(n)
- 最坏情况:
O(n^2)
- 平均时间复杂度:
O(n^2)
空间复杂度:O(1)
稳定性:稳定
插入排序的优点是简单、直观,对于小规模或者基本有序的数组排序非常高效,并且适用于对算法稳定性有要求的场景。受限于 O(n^2)
的时间复杂度,其在处理大数据集时会非常耗时,因此实际应用中通常会选择其他的排序算法对数据进行排序,比如:快速排序、归并排序等更高效的排序算法。
对快速排序算法不了解的小伙伴可以看看我的这篇文章:http://t.csdnimg.cn/4jWYO
归并排序算法后续我也会专门写一篇文章为大家介绍。
PS: 如果这篇文章对你有帮助的话,还请帮忙点个赞~~