插入排序及算法分析

本文深入探讨了直接插入排序算法的工作原理及其实现过程,并通过扑克牌的例子形象地解释了算法的运作方式。此外,还详细分析了算法的时间复杂度,并介绍了循环不变式的概念及其在算法正确性验证中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

插入排序是一种很重要的排序方式,包括直接插入排序,二分插入排序,希尔排序等,这里 以直接插入排序(稳定)为例研究算法分析。

直接插入排序最经典的引入就是扑克牌,所谓插入就是拿着当前牌(第j张),插入到前j-1张牌中,使这j张牌仍然有序,所以伪代码是这样的(n张牌, 储存在数组A[n+1]中):

//扑克牌假定从1到n,第一张显然已经有序,当然插入的牌也有可能插到当前第一张牌之前,也就是第0位
  	for(i = 2; i<=n;i++)
{
	key = A[i];
	j = i-1;
	while(j>0&& A[j]>key)
	{
		A[j+1]  = A[j];
		j--;
	}
A[j+1] = key;
}
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int n;
    while(cin>>n)
    {
        int A[n+2];
        for(int i = 1; i<=n; i++)
            cin>>A[i];     
            for(int i = 2; i<=n; i++)
        {
            int key = A[i];
            int j = i-1;
            while(j>0&& A[j]>key)
            {

                A[j+1] = A[j];
                j--;
            }
            A[j+1] = key;
        }


        for(int i = 1; i<=n; i++)
            cout<<A[i]<<" ";
            cout<<endl;
    }
}

循环不变式:
在上述伪代码中 for(int i = 2; i<=n; i++)的每一次循环,前i-1项都是已经排好序的,这种性质叫做循环不变式,可以用来帮助我们理解算法的正确性,关于循环不变式,必须证明三条性质:
1、初始化: 循环的第一次迭代之前为真
2、保持: 如果循环的每次迭代之前为真,那么下次迭代前仍为真
3、终止: 在循环终止时,不变式为我们提供一个有用的性质,该性质有助于证明算法是正确的

分析算法:
单处理计算模型:RAM模型(随机访问机),作为算法分析时要使用的实现技术模型,包括描述所用资源及其代价。在RAM模型中,指令一条借一条的执行,没有并发操作。
插排算法分析:
通常把一个程序的运行时间描述成其输入规模的函数,一个算法在特定输入上的运行时间是指执行的基本操作数或步数,假定第i行每次执行需要时间ci(常量),那么上述伪代码的执行时间如下
             代价   次数

for(i = 2; i<=n;i++)     c1   n
{ 
key = A[i];         c2   n-1
j = i-1;           c3   n-1
while(j>0&& A[j]>key)    c4  ∑_(i=2)^n▒ti
{ 
A[j+1] = A[j];        c5 ∑_(i=2)^n▒(ti-1)
j–; 					c6   ∑_(i=2)^n▒(ti-1)
} 
A[j+1] = key; 			c7   n-1
}

最坏的情况(ti为 n)
时间为 an^2 + bn + c;但我们真正感兴趣的是运行时间的增长率||增长量级,所以只需要考虑最重要的项,记做Θ(n^2);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值