【数据结构】直接插入排序

在这里插入图片描述

个人主页:Weraphael
✍作者简介:目前正在学习c++和算法
✈️专栏:数据结构
希望大家多多支持,咱一起进步!
如果文章有啥瑕疵
希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论 点赞 收藏 加关注


一、基本思想

【数据结构】直接插入排序_第1张图片

基本思想:把待排序的元素从小到(从大到小)逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列

实际中,玩扑克牌时,整理一副牌从小到大或者从大到小就用到了插入排序的思想

【数据结构】直接插入排序_第2张图片

二、算法原理

  1. 首先序列中的第一个元素(下标为0)是不需要排序的。因为当插入第一个元素时,序列中也没有元素与其比较,因此默认为有序。
  2. 当插入第ii ≥ 1)个元素时,由于要挪动数据,我们拿待插入元素当前数组内的最后一个元素(下标end)进行比较,若a[i] < 数组最后一个元素,则将当前元素向后移动一个单位,并将end--继续向前比较,直到找到合适位置为止。

这里为大家举几个样例

  • 插入1

【数据结构】直接插入排序_第3张图片

  • 插入3

【数据结构】直接插入排序_第4张图片

  • 插入5

【数据结构】直接插入排序_第5张图片

三、代码实现

以下代码以升序为例:

#include 

// n - 元素个数
void InsertSort(int* a, int n)
{
	// 数组第一个元素不需要参与排序
	// 下标从1开始
	for (int i = 1; i < n; i++)
	{
		// end - 每一次数组最后一个元素的下标
		// InsertNum - 要插入的元素
		int end = i - 1; 
		int InsertNum = a[i];
		
		while (end >= 0)
		{
			// 如果插入的元素比当前元素小,就要往后挪动数据
			if (a[end] > InsertNum)
			{
				a[end + 1] = a[end];
				end--;
			}
			// 插入比当前元素大,则直接插入
			else
			{
				a[end + 1] = InsertNum;
				break;
			}
		}
		//当循环结束后,可能存在头插
		if (end == -1)
		{
			a[end + 1] = InsertNum;
	    }
	}
}

当然以上代码在插入过程中有重复代码,因此可以整合

#include 

// n - 元素个数
void InsertSort(int* a, int n)
{
	// 数组第一个元素不需要参与排序
	// 下标从1开始
	for (int i = 1; i < n; i++)
	{
		// end - 每一次数组最后一个元素的下标
		// InsertNum - 要插入的元素
		int end = i - 1; 
		int InsertNum = a[i];
		
		while (end >= 0)
		{
			// 如果插入的元素比当前元素小,就要往后挪动数据
			if (a[end] > InsertNum)
			{
				a[end + 1] = a[end];
				end--;
			}
			// 插入比当前元素大,则直接插入
			else
			{
				break;
			}
		}
		// 当循环结束后,存在两种情况
		// 1. 头插
		// 2. break跳出来的 
		// 以上情况直接插入即可
		a[end + 1] = InsertNum;	
	}
}

【运行结果】

【数据结构】直接插入排序_第6张图片

四、特性总结

  1. 时间复杂度

最好情况:原数组已经是按需求有序了,每趟只需与前面的有序元素序列的最后一个元素进行比较,总比较次数为n - 1,时间复杂度为 O(N);

最坏情况:假设要排升序,原数组是逆序的情况下,O(N2)

综上,直接插入排序的时间复杂度为O(N2)

  1. 空间复杂度

O(1)。只用到了一个数组

  1. 稳定性

插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。如果碰见一个和插入元素相等的,那么将会把待插入元素放在相等元素的后面。所以,相等元素的相对的前后顺序没有改变,所以插入排序是 稳定 的。

你可能感兴趣的:(数据结构,数据结构,算法,c++,开发语言,visualstudio)