插入排序(Insertion Sort)

插入排序(Insertion Sort)

基本概念

插入排序是一种简单的排序,适合对较小的数据量进行排序,插入排序的基本思想类似于整理扑克牌,即从第一个元素开始将第\(n\)个未排序的元素插入到前面\(n-1\)个有序的数据中

示例图:
img

性质

时间复杂度

再最优的情况下,即所有元素都是有序的情况下,插入排序仍需从第二个元素开始遍历一遍数据并进行比较,因此插入排序的最优时间复杂度为\(O(N)\)。最坏的情况下,即所有元素都是逆序的情况下,第\(n\)个元素需要与前面\(n-1\)个元素进行比较,最后的结果就是\(1+2+……+(n-1)\),也就是\(n^2/2\),也就是说时间复杂度为\(O(N^2)\)平均时间复杂度为\(O(N^2)\)

空间复杂度

插入排序不需要额外的空间,所以空间复杂度为\(O(1)\)

稳定性

当一个元素向前比较时,遇到相同的元素就会停下,并插入其后,相对位置不变,所以插入排序是稳定的。

实现

template <typename T>
inline void InsertSort(T* const ptr, const size_t count, bool cmp(const T* v1, const T* v2) = DefaultCmp)
{
	if (!count || !ptr) {
		return;
	}
	for (size_t i = 1; i < count; i++) {	//从第二个元素开始
		T value = *(ptr + i);	//记录第i个元素
		long long j = i - 1;	//要插入元素的前一个元素
		for (; j >= 0 && cmp(ptr + j, &value);) {	//cmp返回true时执行
			//*(ptr + j + 1) = *(ptr + j);	//若第j个元素比value大,第j个元素后移
			j--;	//索引前移
		}
		//使用memmove在元素内存很大时可显著提速
		std::memmove(ptr + j + 2, ptr + j + 1, sizeof(T) * (i - j - 1));
		*(ptr + j + 1) = value;	//插入元素
	}
}

实现时注意第n个元素不断与前面元素比较时可先不对前面的元素进行操作,而是仅将索引前移,最后在统一移动,可提高效率。

posted @ 2025-10-14 00:00  单身喵  阅读(41)  评论(0)    收藏  举报