INSORTION_RECUSION_SORT ( A , n ) //A[1..n]
if n > 2 //数组元素在2个以上时将数组进行拆分……………………………………………………c1
INSORTION_RECUSION_SORT ( A , n - 1 ) //将前 n - 1位进行插入排序……………………c2
key = A [ n ] //将数组中的最后一位设为待比较值key………………………………………………c3
i = n - 1 //要比较的数组元素为n-1个………………………………………………………………c4
while i > 0 and A [ i ] > key //当标志位没到数组左尽头,且第A [ i ]比A [ n ](key)大时…………c5
A [ i + 1 ] = A [ i ] //A [ i ]移动到A [ i +1 ]的位置,当前值右移一位………………………………c6
i = i - 1 //标志位左移一位……………………………………………………………………………c7
A [ i + 1 ] = key…………………………………………………………………………………………c8
//比较完毕后,最后一个A [ i ]的位置因为与A [ i +1]交换了,所以是空出来的,这个位置扫塌而待在空中与各个A [ i ]做比较的A[ n ]的值key,A[ n ]从一开始失去了位置,到最后它的值终于在所有比它大的A[ i ]之前的位置安了家。并完成了从小到大的排序。PS:因为最后一步有个 i = i - 1 ,所以是A [ i + 1 ] = key,而不是A [ i ] = key。
首先,题目让我们考虑最差的情况,即A[1..n]是从大到小排序的,伪代码第6行while中的每一次交换都不能省,且都要交换到i=0结束。
先考虑T(n)的情况,设在每个函数中while循环一共要执行ti次。
T(n)=c1+c2+c3+c4+ti*c5+(ti-1)*(c6+c7)+c8+T(n-1)
T(n)=(c5+c6+c7)*ti+c1+c2+c3+c4-c6-c7+c8+T(n-1)
因为c1~8都是常数,复杂度都为O(1),不妨设k1=c5+c6+c7,k2=c1+c2+c3+c4-c6-c7+c8。
则,
T(n)=k1*ti+k2+T(n-1)
当n=n时其中c5处,想想最后一个元素(最小数)待排序的情况,前面的每个数都比它大,即要完成(n-1)次比较,算上最后i=0结束循环那次,一共ti=(n-1)+1=n。
T(n)=n*k1+k2+T(n-1),同理,
T(n-1)=(n-1)*k1+k2+T(n-2),
T(n-3)=(n-3)*k1+k2+T(n-3),
……
T(3)=3*k1+k2+T(2),
T(2)=2*k1+k2.
最后我们来验证一下T(2)的值。考虑递归结束时,即n=2时,
直观地,
T(2)=c1+c3+c4+2*c5+c6+c7+c8,我们将k1=c5+c6+c7,k2=c1+c2+c3+c4-c6-c7+c8代入原式,可得
T(2)=2*k1+k2。
验证无误。
将T(2)到T(n-1)依次代入上一级调用。
显然,
T(n)=(2+3+4+……+(n-1)+n)*k1+n*k2,
T(n)=0.5*k1*n*n+(0.5*k1+k2)*n-k1-k2.
其中k1,k2均为常数,
故迭代插入排序算法的时间复杂度为O(n^2)。