排序算法之插入排序篇
插入排序
思路:
就是将没有排序的元素逐步地插入到已经排好序的元素后面,保持元素的有序
视频的实现过程如下:
插入排序全过程
代码实现过程如下:
public static void Insertion(int[] arr) {
for (int i = 1; i < arr.length; i++) { // 从第二个元素开始
int key = arr[i]; // 当前要插入的元素
int j = i - 1; // 已排序部分的最后一个位置
// 将已排序部分大于key的元素向右移
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j]; // 向右移动元素
j--; // 继续往左移动
}
// 将key插入到正确的位置
arr[j + 1] = key;
}
}
时间复杂度:
插入排序的时间复杂度其实分为最坏情况、最好情况和平均情况,
1. 最坏情况(Worst Case):
最坏的情况发生在数组是逆序的情况下。也就是说,数组中的每一个元素都比它前面的元素大。
- 假设我们有一个数组
[5, 4, 3, 2, 1]
,它完全是逆序的。 - 对于每个元素,插入排序都需要将它和前面所有的元素比较,直到它被插入到最前面。
对于第一个元素,已经是排序好了的,所以不需要比较。
- 对第二个元素,
4
,需要比较一次(和5
比较),然后把它插入到第一个位置。 - 对第三个元素,
3
,需要和前面的5
和4
都比较,再把它插入到第三个位置。 - 对第四个元素,
2
,需要和前面的三个元素5
、4
、3
都比较,再插入到第四个位置。 - 对最后一个元素,
1
,需要和前面所有四个元素比较,再插入到最前面。
这种情况,每个元素的比较次数逐渐增多,总的比较次数大约是:
- 第一个元素比较 0 次
- 第二个元素比较 1 次
- 第三个元素比较 2 次
- …
- 第n个元素比较 n-1 次
因此,比较的总次数是:
[
0 + 1 + 2 + … + (n-1) = \frac{n(n-1)}{2}
]
这就是二次方的增长,所以最坏情况下的时间复杂度是:O(n^2)。
2. 最好情况(Best Case):
最好情况发生在数组本身已经是有序的情况下。即所有的元素已经在正确的位置,不需要任何交换。
- 假设我们有一个数组
[1, 2, 3, 4, 5]
。 - 对于每一个元素,它已经在排序好的部分中,所以每次插入时都只需要比较一次,发现它的位置已经正确,无需做交换。
所以对于每个元素,只需要进行一次比较,总的时间复杂度就是O(n),即线性时间。
3. 平均情况(Average Case):
平均情况就是假设数据是随机的,每个元素大约需要和一半的已排序部分比较。
每个元素平均需要比较 n/2
次。因为是随机的情况,所以比较的次数大致是:
[
\frac{n}{2} \times n = O(n^2)
]
所以,平均情况下,插入排序的时间复杂度也是O(n^2)。
总结:
- 最坏情况:O(n^2)(数组逆序时)
- 最好情况:O(n)(数组已排序时)
- 平均情况:O(n^2)(随机排列的情况)
因此,虽然插入排序在最好的情况下效率较高,但在大多数情况下,它的时间复杂度是 O(n^2),这使得它在处理大规模数据时不太高效。
如果数组已经基本排好序或者只有少量元素需要调整,插入排序还是一个不错的选择,因为它的空间复杂度是 O(1),即它不需要额外的空间来存储临时数据。
原文地址:https://blog.csdn.net/fayifenjihuang/article/details/144087389
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!