选择插入排序算法(通过简单示例来学习分析和设计算法的要点)

这篇博客介绍了插入排序算法,通过伪代码展示了算法过程,并分析了其在最好(已排序)和最坏(反向排序)情况下的时间复杂度。在已排序情况下,算法表现为线性时间复杂度;而在反向排序时,算法呈现平方时间复杂度,属于二次函数。讨论了关注最坏情况的原因,并强调在算法分析中通常关注增长率和量级,而非低阶项和常数系数。
摘要由CSDN通过智能技术生成

经过学习了上次的简单的概念,下面来看一个简单的插入排序算法
我在算法学习这里都要使用伪代码,而不是C语言,这样也能避免使用语言特性。或者使用伪代码更易懂。
下面关于分析算法的一些小知识
我们规定我们要使用的实现技术的模型是一种随机访问机(RAM)来执行我们的操作,在这个模型中指令一条接一条的执行,没有并发操作
RAM包含真实计算机中常见的指令:算术指令、数据移动指令、控制指令
这些操作所需的时间都是常量
值得注意的是指数运算,xy 运算需要若干个指令运算,所需时间不是个常量,但是许多计算机都有左移的操作,2x可以看做是左移右移得到的,所以是个常量级操作
在RAM的模型下,分析算法需要的数学工具包括组合学概率论代数技巧,以及识别一个公式最有意义的一项的能力。
分析插入排序算法的过程依赖于输入规模,显然排序三个数和1000个数是不一样的
输入规模的最佳概念依赖于所要研究的问题
一个算法在输入上的运行时间是指执行的基本操作或者步数。我们假定执行到第i步的时间为ci(常量),注释的时间为0,循环的判断也是需要时间的。
下面来看这个排序算法

插入排序A数组                                                  代价           次数
for j=2 to A.length                                            c1             n
	key = A[j]                                                 c2             n-1
	//insert A[j] into the sorted array A[1,j-1].               0             n-1
	i=j-1													   c4             n-1
	while i>0 and A[i]>key									   c5             t2+t3+....tn
		A[i+1]=A[i]											   c6             (t2-1)+(t3-1)+....(tn-1)
		i=i-1												   C7             (t2-1)+(t3-1)+....(tn-1)
	A[i+1]=key   											   c8  			  n-1

将上面的写出具体的运行时间
T ( n ) = c 1 n + c 2 ( n − 1 ) + c 4 ( n − 1 ) + c 5 ∑ j = 2 n t j + c 6 ∑ j = 2 n ( t j − 1 ) + c 7 ∑ j = 2 n ( t j − 1 ) + c 8 ( n − 1 ) T_{(n)}=c_1n+c_2(n-1)+c_4(n-1)+c_5\sum_{j=2}^nt_j+c_6\sum_{j=2}^n(t_j-1)+c_7\sum_{j=2}^n(t_j-1)+c_8(n-1) T(n)=c1n+c2(n1)+c4(n1)+c5j=2ntj+c6j=2n(tj1)+c7j=2n(tj1)+c8(n1)
如果数组已经排好序,则是最佳情况
T ( n ) = c 1 n + c 2 ( n − 1 ) + c 4 ( n − 1 ) + c 5 ( n − 1 ) + c 8 ( n − 1 ) T_{(n)}=c_1n+c_2(n-1)+c_4(n-1)+c_5(n-1)+c_8(n-1) T(n)=c1n+c2(n1)+c4(n1)+c5(n1)+c8(n1)
= ( c 1 + c 2 + c 4 + c 5 + c 8 ) n − ( c 1 + c 2 + c 4 + c 5 + c 8 ) =(c_1+c_2+c_4+c_5+c_8)n-(c_1+c_2+c_4+c_5+c_8) =(c1+c2+c4+c5+c8)n(c1+c2+c4+c5+c8)
这时候可以表示成an+b ,因此此时它是个线性函数

倘若输入数组按照了反向排序,则导致最坏情况我们必须将每个元素A[j]与整个已排序子数组A[i,j-1]进行比较,所以对j=2,3,…,n有tj=j
∑ j = 2 n = n ( n + 1 ) 2 − 1 \sum_{j=2}^n=\frac{n(n+1)}2-1 j=2n=2n(n+1)1
∑ j = 2 n ( j − 1 ) = n ( n − 1 ) 2 \sum_{j=2}^n(j-1)=\frac{n(n-1)}2 j=2n(j1)=2n(n1)
那么运行时间为
T ( n ) = c 1 n + c 2 ( n − 1 ) + c 4 ( n − 1 ) + c 5 ( n ( n − 1 ) 2 − 1 ) + c 6 ( n ( n − 1 ) 2 ) + c 7 ( n ( n − 1 ) 2 ) + c 8 ( n − 1 ) T_{(n)}=c_1n+c_2(n-1)+c_4(n-1)+c_5(\frac{n(n-1)}2-1)+c_6(\frac{n(n-1)}2)+c_7(\frac{n(n-1)}2)+c_8(n-1) T(n)=c1n+c2(n1)+c4(n1)+c5(2n(n1)1)+c6(2n(n1))+c7(2n(n1))+c8(n1)
= ( c 5 2 + c 6 2 + c 7 2 ) n 2 + ( c 1 + c 2 + c 4 + c 5 2 − c 6 2 − c 7 2 + c 8 ) n − ( c 2 + c 4 + c 5 + c 8 ) =(\frac{c_5}2+\frac{c_6}2+\frac{c_7}2)n^2+(c_1+c_2+c_4+\frac{c_5}2-\frac{c_6}2-\frac{c_7}2+c_8)n-(c_2+c_4+c_5+c_8) =(2c5+2c6+2c7)n2+(c1+c2+c4+2c52c62c7+c8)n(c2+c4+c5+c8)
这时候是个an2+bn+c其中a,b,c依赖于语句代价**ci**所以是二次函数。是平方性算法

这里我们分析了算法的最佳情况和最坏情况
然而我们经常来关注算法的最坏情况
以下有三点理由:
1.最坏情况给定了一个上界,知道了这个界,就能确保该算法不会需要更长时间,就不必要去猜测更复杂的情况并可以期望它不会变的更坏
2.对于某些算法,最坏情况经常出现,比如搜索算法
3.“平均情况”往往跟最坏情况一样差
我们同样关注的是运行时间的增长率增长量级,所以我们通常只考虑最重要的项,因为n的值很大的时候,低阶项相对来说不重要,有时候甚至会忽略高阶项的常数系数。

所以此算法具有最坏运行时间 θ ( n 2 ) \theta(n^2) θ(n2)

蒟蒻的今天的总结到这里。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值