简单易懂排序算法(三)【直接插入排序】

直接插入排序基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。

根据此思想我们可以写出如下代码:

void InsertSort(vector<int>& vec)
{
	int n = vec.size();
	int i, j, tmp;
	for (i = 1; i < vec.size(); ++i)
	{
		tmp = vec[i];  //将当前待插入的元素提出
		for (j = i - 1; j >= 0 && vec[j] > tmp; --j)
			vec[j + 1] = vec[j];  //将已经排好序的序列往后移一位,找到插入位置则停止
		vec[j + 1] = tmp;  //将元素插入其中
	}
}

简单测试
测试序列:9,1,5,8,3,7,4,6,2
在这里插入图片描述
从测试所得结果也可以看出,每一次将第i位元素插入到前面已有的有序序列中,代码的关键在于将已有的有序序列往后移找到合适的插入位置

时间复杂度分析

  • 当最好的情况,也就是要排序的表本身是有序的,比如待排序序列为:1,2,3,4,5,6,7,8,9;这样子就不必进行移位插入这一步骤,因此这种情况算下来时间复杂度为O(n)
  • 当最坏的情况下,即待排序序列为逆序,则其需要比较的次数为:

∑ i = 1 n − 1 ( i ) \sum\limits_{i=1}^{n-1} (i) i=1n1(i) = 1 + 2 + … + n - 1 = n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1)

其需要移动的次数为( t m p = v e c [ i ] ; v e c [ j + 1 ] = t m p ; tmp = vec[i]; vec[j + 1] = tmp; tmp=vec[i];vec[j+1]=tmp;):

∑ i = 1 n ( i + 2 ) \sum\limits_{i=1}^n (i + 2) i=1n(i+2) = 1 + 2 + 2 + 2 … + n + 2 = ( n + 4 ) ( n − 1 ) 2 \frac{(n + 4)(n - 1)}{2} 2(n+4)(n1)

  • 如果排序记录是随机的,那么根据概率相同的规则,平均比较和移动次数约为 n 2 4 \frac{n ^2}{4} 4n2
  • 因此,可以得出,直接插入排序的时间复杂度为O(n^2)
  • 由于插入排序是两两比较,且两者如果相同并不会交互次序,所以是一种稳定的排序算法

测试代码

#include <iostream>
#include <vector>
using namespace std;

void InsertSort(vector<int>& vec);
void PrintStep(vector<int> vec, int n, int i);
void PrintResult(vector<int> vec, int n);

void InsertSort(vector<int>& vec)
{
	cout << "--------------直接插入排序--------------" << endl;
	int n = vec.size();
	int i, j, tmp;
	for (i = 1; i < vec.size(); ++i)
	{
		if (vec[i] < vec[i - 1]) 
		{
			tmp = vec[i];
			for (j = i - 1; j >= 0 && vec[j] > tmp; --j)
				vec[j + 1] = vec[j];			
			vec[j + 1] = tmp;
		}
		PrintStep(vec, n, i);
	}
	cout << "最终排序结果为:";
	PrintResult(vec, n);
}

void PrintStep(vector<int> vec, int n, int i)
{
	cout << "第" << i << "次排序结果: ";
	for (int j = 0; j < n; ++j)
		cout << vec[j] << ' ';
	cout << endl;
}

void PrintResult(vector<int> vec, int n)
{
	for (int j = 0; j < n; ++j)
		cout << vec[j] << ' ';
	cout << endl;
}
int main(int argc, char **argv)
{
	int a[] = {9,8,7,6,5,4,3,2,1};
	vector<int> vec(a, a+9);
	InsertSort(vec);
	return 0;
} 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值