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

大家好,我是苏貝,本篇博客带大家了解插入排序,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️


目录

  • [一. 基本思想](#一. 基本思想)
  • [二. 插入排序详解(以升序为例)](#二. 插入排序详解(以升序为例))
  • [三. 对比冒泡排序](#三. 对比冒泡排序)

一. 基本思想

直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列

实际中我们玩扑克牌时,就用了插入排序的思想

二. 插入排序详解(以升序为例)

思路:

我们让数组下标为[0,end]的有序,现插入a[end+1],使数组下标为[0,end+1]的有序。

最开始时,我们让end==0,这样就是插入a[1],让数组下标为[0,1]的有序

当插入第i(i>=1)个元素时,前面的array[0],array[1],...,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],...的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移

下面代码中,因为最后一个元素一定是tmp,所以end+1<n,所以end<n-1,因为end=i,所以i<n-1。

c 复制代码
void InsertSort(int* a, int n)
{
	//假设[0,end]有序,将a[end+1]插入再次形成有序
	for (int i = 0; i < n - 1; i++)
	{
		int end = i;
		int tmp = a[end + 1];
		while (end >= 0)
		{
			if (a[end] > tmp)
			{
				a[end + 1] = a[end];
				end--;
			}
			else
				break;
		}
		a[end + 1] = tmp;
	}
}

插入排序的时间复杂度是多少?

时间复杂度是在最坏情况下计算的,插入排序的最坏情况就是降序

第一次:1

第二次:2

......

第N-1次:N-1

全部加起来=1+2+......+(N-1) = (N+1)(1+N-1)/2 = N*(N-1)/2,所以时间复杂度为O(N^2)

直接插入排序的特性总结:

1.元素集合越接近有序,直接插入排序算法的时间效率越高

2.时间复杂度:O(N^2)

3.空间复杂度:O(1),它是一种稳定的排序算法

4.稳定性:稳定

三. 对比冒泡排序

点击了解冒泡排序

c 复制代码
void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}


void BubbleSort(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n - i - 1; j++)
		{
			if (a[j] > a[j + 1])
			{
				Swap(&a[j], &a[j + 1]);
			}
		}
	}
}

冒泡排序的时间复杂度是多少?

总共需要冒泡N-1次

第一次冒泡:循环N-1次

第二次冒泡:N-2

第三次冒泡:N-3

...

第N-1次冒泡:1

全部加起来=1+2+......+(N-1) = (N+1)(1+N-1)/2 = N*(N-1)/2,所以时间复杂度为O(N^2)

所以插入排序和冒泡排序的时间复杂度是一样的,那能说明它们的效率是一样的吗?在这里我们用一个函数来测试两个排序的性能。让两种排序都排列同样的100000个随机数字,比较2个排序的时间。rand函数用来生成随机值,clock函数用来返回程序运行的时间。因为2种排序用的时间都比较长,所以在这里我们将Debug换成Release

c 复制代码
void TestOP()
{
	srand(time(0));
	const int N = 100000;
	int* a1 = (int*)malloc(sizeof(int) * N);
	int* a2 = (int*)malloc(sizeof(int) * N);

	for (int i = 0; i < N; ++i)
	{
		a1[i] = rand();
		a2[i] = a1[i];
	}

	int begin1 = clock();
	InsertSort(a1, N);
	int end1 = clock();

	int begin2 = clock();
	BubbleSort(a7, N);
	int end2 = clock();

	printf("InsertSort:%d\n", end1 - begin1);
	printf("BubbleSort:%d\n", end2 - begin2);

	free(a1);
	free(a2);
}

结果如下:我们发现,虽然它们的时间复杂度在同一层级,但是插入排序还是优于冒泡排序的。



好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

相关推荐
ZZZ_O^O17 分钟前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
代码雕刻家1 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
Kalika0-03 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
代码雕刻家3 小时前
课设实验-数据结构-单链表-文教文化用品品牌
c语言·开发语言·数据结构
小字节,大梦想4 小时前
【C++】二叉搜索树
数据结构·c++
我是哈哈hh5 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
丶Darling.5 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
labuladuo5205 小时前
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)(思维,set)
数据结构·c++·算法
Indigo_code6 小时前
【数据结构】【链表代码】合并有序链表
数据结构·windows·链表
jiyisuifeng19916 小时前
代码随想录训练营第54天|单调栈+双指针
数据结构·算法