经典排序算法(一)插入排序

基本思想

插入排序的思想如同它的名字一般:“插入”。

  • 首先,我们可以将待排序的无序序列的首元素看作是一组有序序列a,序列元素个数为1,其后是一组无序序列b,元素个数为n-1。
  • 每次取出无序序列的第一个元素b1,也即有序序列末尾元素的下一个元素。
  • 将该元素b1从后往前,依次和有序序列中的元素ai比较。
  • 被比较的有序元素ai如果大于该元素b1,有序元素ai向后移动一位,直到找到第一个小于该元素b1值(升序)的元素ak,将无序元素b1插入到该有序序列元素ak的下一个位置。
  • 重复上面的过程,直到无序序列中没有元素,序列就被排序完成啦!是不是很简单呀?

算法流程

例如,有一个待排序的无序序列 {28,44,13,22,19,11,49,16,16,42 }
该序列通过插入排序得到有序序列的动画效果如下:

插入排序算法动画

动画来源:算法可视化网站

看完这个动画,结合文章中对该算法的基本思想描述,能否自己写出插入排序的代码?

代码实现

  • 语言:C++
  • 序列存储结构:一维数组

在阅读这段代码之前,我先补充一个知识:数组初始化时,第0个位置不存放无序元素,该位置是用作插入排序的哨兵位置。引入哨兵的好处在于减少判断循环边界位置的比较次数,提高程序运行速度,话不多说,上代码:

/*
参数1:arr。一维数组的首地址
参数2:length。一维数组的元素个数(长度)
*/
void InsertSort(int* arr, int length)
{
    
    
	for (int i = 2; i <= length; ++i)
	{
    
    
		//设置哨兵
		arr[0] = arr[i];
		int j = i - 1;
		for (; arr[j] > arr[0]; --j)
		{
    
    
			arr[j + 1] = arr[j];
		}
		arr[j + 1] = arr[0];
	}
}

总结

  • 算法时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 算法空间复杂度: O ( 1 ) O(1) O(1)
  • 算法是否稳定:稳定
    算法稳定指的是序列通过算法排序后,比较值相同(key)的两个元素相对顺序不会发生改变
  • 算法适用范围:由于插入排序算法简单,高效,且具有稳定性,通常应用于序列元素较少的排序场合。

猜你喜欢

转载自blog.csdn.net/qq_42518941/article/details/114500672