💬💬作者有话想说:
💟作者简介:我目前是一个在校学生,想通过自己的学习努力让自己的技术、知识都慢慢提升,希望我们一起学习呀~💜💜💜
☂️兴趣领域:目前偏向于前端学习 💜💜💜
🎬> 活动地址:CSDN21天学习挑战赛
💜有话想说:写博客、记笔记并不是一种自我感动,把学到的东西记在脑子里才是最重要的,在这个过程中,不要浮躁,希望我们都可以越来越优秀!💜💜💜
🪀语言说明:代码实现我会用Python/C++~
学这个之前,我们要知道二分查找和直接插入排序!
- 二分插入排序也叫作折半插入排序,其实就是直接插入排序的一直改进,运用了二分的思想。
- 所谓二分插入排序,就是不断的依次将元素插入前面已排好序的序列中。由于前半部分为已排好序的数列,这样我们不用按顺序依次寻找插入点,可以采用折半查找的方法来加快寻找插入点的速度。这样在数据量很大的时候,算法的效率就会很高!


💡💡思路:
💡💡
- 最好的情况:最好的情况下,列表元素已按关键字从小到大有序排列,每次只需要与前面有序元素的最后一个元素比较1次,移动2次元素,总的比较次数为n-1,元素移动次数为2(n-1),算法复杂度为O(n)
- 最坏的情况:坏情况下每一行代码都被执行,即全部反向有序,最坏时间复杂度为O(n^2)
- 综合以上,直接插入排序的时间复杂度为O(n^2)
💡💡:
算法执行过程中仅需要几个额外的变量,所以空间复杂度为O(1)
C++代码:
#include
using namespace std;
void Array(int arr[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("%4d", arr[i]);
printf("\n");
}
int main()
{
int arr[] = {5,9,23,6,9,18,2,66};
int temp, i, j, low, high, mid, n;
n = sizeof(arr) / sizeof(arr[0]);
Array(arr, n);
printf("折半插入排序:\n");
for (i = 1; i < n; i++)
{
temp = arr[i];
for (low = 0, high = i - 1; high >= low;)
{
// 防止溢出
mid = left +(low - high) / 2;
if (temp < arr[mid])
high = mid - 1;
else
low = mid + 1;
}
for (j = i - 1; j >= low; j--)
a[j + 1] = a[j];
arr[low] = temp;
Array(arr, n);
}
}
Python代码:
def InsertSort(arr):
for i in range(1, len(arr)):
tmp = arr[i]
low = 0
high = i - 1
# 将范围折半再查找
while low <= high:
mid = int(low + (high - low) / 2)
if tmp > arr[mid]:
low = mid + 1
else:
high = m - 1
# arr[high]的元素比tmp小
j = i - 1
while j >= high + 1:
arr[j + 1] = arr[j]
j -= 1
# 将tmp放在arr[high]之后
arr[high + 1] = tmp
if __name__ == "__main__":
arr = [5,9,23,6,9,18,2,66]
InsertSort(arr)
print(arr)
优点:
折半插入排序在无序集情况下优于直接排序
缺点:
在近似有序集下,折半插入排序比较次数较多。