感谢阅读!❤️
如果这篇文章对你有帮助,欢迎 **点赞** 👍 和 **关注** ⭐,获取更多实用技巧和干货内容!你的支持是我持续创作的动力!
**关注我,不错过每一篇精彩内容!**
一、插入排序的算法思路
插入排序(Insertion Sort)是一种简单直观的排序算法,其基本思想是:将数组分为两部分——已排序部分和未排序部分。初始时,已排序部分只包含第一个元素,其余为未排序部分。每次从未排序部分取出一个元素,将其插入到已排序部分中的适当位置,使得整个已排序部分保持有序。
二、算法步骤
- 第一步:初始化,第一个元素默认视为已排序部分
- 第二步:依次从未排序部分取数,从第二个元素开始,逐个遍历未排序部分
- 第三步:向前比较,将当前元素与前面已排序元素逐一比较,若当前元素比前面的元素小,则向后移动前面的元素,直到找到插入位置。
- 第四步:重复第三步,直至所有未排序元素都被插入到正确位置。
三、示例数组排序过程
数组:
[5, 8, 5, 2, 9]
的排序过程
- 第一轮:已排序区间为
[5]
,未排序区间为[8, 5, 2, 9]
,将第2个元素8
与已排序部分[5]
进行比较,因为8 > 5
,无需交换位置 →[5, 8, 5, 2, 9]
。 - 第二轮:已排序区间为
[5, 8]
,未排序区间为[5, 2, 9]
,将第3个元素5
与已排序部分[5, 8]
进行比较,因为5 < 8
,因此将8
后移一位,因为5 = 5
,因无需交换位置,然后将5
放入正确位置 →[5, 5, 8, 2, 9]
。 - 第三轮:已排序区间为
[5, 5 ,8]
,未排序区间为[2, 9]
,将第4个元素2
与已排序部分[5, 5, 8]
进行比较,因为2 < 8
,因此将8
后移一位,因为2 < 5
,因此将5
后移一位,因为2 < 5
,因此将5
后移一位,然后将2
放入正确位置 →[2, 5, 5, 8, 9]
。 - 第四轮:已排序区间为
[2, 5, 5 ,8]
,未排序区间为[9]
,将第5个元素9
与已排序部分[2, 5, 5, 8]
进行比较,因为9 > 8
,因无需交换位置 →[2, 5, 5, 8, 9]
。
四、代码实现
import java.util.Arrays;
public class InsertionSort {
public static void main(String[] args) {
//测试代码
int[] arr = {5, 8, 5, 2, 9};
insertionSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void insertionSort(int[] arr){
if(arr == null || arr.length < 2){
return;
}
for(int i = 1; i < arr.length; i++){
//取出未排序部分中的数
int key = arr[i];
//当前元素的前一个元素索引
int j = i - 1;
//比较已排序的元素:从当前元素的前一个元素开始比较,若当前元素的值小于前面元素的值,向后移动前面元素
while(j >= 0 && key < arr[j]){
//交换俩个元素
arr[j+1] = arr[j];
j--;
}
//插入当前元素到合适位置
arr[j+1] = key;
}
}
}
五、时间复杂度分析
时间复杂度:最坏情况为
O(n²)
,最好情况为O(n)
-
最坏情况(逆序排列):
- 输入数组为逆序排列,如
[9, 7, 5, 3, 1]
- 每轮需要比较并移动最多 i 次
- 总比较次数为
1 + 2 + ...+ (n-2) + (n-1) = n(n-1)/2
,因此时间复杂度为O(n²)
。
- 输入数组为逆序排列,如
-
平均情况(随机排列):
- 与最坏情况类似,平均需要
n(n-1)/4
次比较和交换。因此时间复杂度仍为O(n²)
。
- 与最坏情况类似,平均需要
-
最好情况(已有序):
- 输入数组为有序排列,如
[1, 3, 5, 7, 9]
- 只需比较 n-1 次,无需移动元素。因此时间复杂度为
O(n)
。
- 输入数组为有序排列,如
根据三种情况。得出插入排序的时间复杂度为:最坏情况为 O(n²)
,最好情况为 O(n)
六、空间复杂度分析
空间复杂度:
O(1)
- 插入排序是
原地排序算法
,仅需常数级的额外空间(如临时变量用于交换元素)。 - 无需额外数组或数据结构,因此空间复杂度为
O(1)
。
七、稳定性分析
稳定性:
稳定排序
原因:当遇到相等元素时,不会改变它们的相对顺序。例如,插入过程中若 key == arr[j],则直接插入其后,不交换位置。
八、适用场景
- 小规模数据(如几十个元素)
- 部分有序的数据(如实时处理流数据)
- 在线排序(数据逐步到达,动态插入)
- 作为其他复杂排序算法(如归并排序、快速排序)的小数组优化手段
九、总结
特性 | 描述 |
---|---|
时间复杂度 | 最坏/平均:O(n²),最好:O(n) |
空间复杂度 | O(1) |
稳定性 | 稳定 |
适用场景 | 小型数据集、在线排序、部分优化场景 |
优点 | 实现简单,逻辑清晰 、对部分有序数据适应性强 |
缺点 | 时间复杂度高,不适用于大规模数据 |