直接插入排序是一种简单的插入排序算法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列
过程:当插入第i(i>=1)个元素时,前面的array[0],…,array[i-1]已经有序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码依次比较,找到插入位置后将原来位置上的元素顺序后移,将array[i]插入
Note:
对于数组中的第一个数据,不需要进行比较,因此第一步操作的是a[1]处的数据,区间[0,0]上的数据即a[0]这一个数据是有序的,因此外层循环只需要对n-1次,对a[1]到a[n-1]共n-1个数据进行处理
对于要处理的a[i],依次与a[i-1],a[i-2]比较,如果大于a[i]则交换(升序排列的情况)
优化:备份i处的数据,依次与a[i-1],a[i-2]比较,大于a[i]则向后移动一个位置,否则在小于a[i]的数据元素的后一个位置插入a[i]
时间复杂度与空间复杂度:
插入排序是在存放原数据的数组上进行操作,所以直接插入排序算法的空间复杂度是O(1)
1️⃣当原数据的序列是逆序时,为最坏情况,此时直接插入排序算法的时间复杂度是O(N^2)
如上图,序列逆序时,数据的挪动次数为1+2+3+…+n-1 = n(n-1)/2
所以时间复杂度为O(N^2)
2️⃣当原数据的序列有序时,为最好情况,此时直接插入排序算法的时间复杂度是O(N)
如上图:序列顺序排列时,总共进行了n-1次比较,没有数据的挪动
因此时间复杂度为O(N)
总结:元素集合越接近有序,直接插入排序算法的时间效率越高
//直接插入排序
void Insersort(std::vector<int>& nums) {
int n = nums.size();
for (int i = 0; i < n - 1; i++) {
int end = i;
int temp = nums[end + 1];
while (end >= 0) {
if (nums[end] > temp) {
nums[end + 1] = nums[end];
--end;
}
else {
break;
}
}
nums[end + 1] = temp;
}
}