常用算法的递归实现问题分析
——针对《数据结构与程序设计》by Robert.L.Kruse
直接或者间接调用自身的算法称为递归算法。在程序设计中,递归实现是一种结构清晰,可读
性强的方法。它经常和分治法结合使用,即对于一个复杂的问题,我们可以考虑先将其反复的
分解成相似的子问题,直到子问题规模小到可以轻易解决。注意,子问题的问题规模必须比原
问题小且简单。 将求出的小规模问题的解合并为一个更大规模问题的解,自底向上逐步求出原
来问题的解。
在对问题进行递归分解之前,必须确定该递归过程的终止条件;必须明确递归分解步骤的精确
形式。
一,快速排序
基本思想(连续存储):首先,一般选择位于数组中部的元素作为枢轴。然后将该数组分成两部
分(两个子数组),位于枢轴前面的元素都比枢轴元素小,以后的都比枢轴元素大。其后反复做
同样的递归分解,直到满足终止条件:high<=low.(low,high分别表示子数组头元素和尾元
素的序号)最后将所有子数组自底向上合并,即得到一个有序数组。
算法复杂度分析:
(面试时注意这里经常被问到)
首先快速排序的平均时间复杂度是O(nlogn),最坏情况下(每次被分成1,n-1)两部分,时间复杂度是
O(n^2).这里主要考察交换swap次数。
假设p(排号)被选作哨兵,则partition后,数列被划分了1,...,p-1和p+1,...,n两部分
s(n,p)=(p+1)+s(p-1)+s(n-p)
s(n,1)+s(n,2)+....+s(n,n)=(1+1)+s(1-1)+s(n-1)+(2+1)+s(2-1)+s(n-2)+...(n+1)+s(n-1)+s(0)
[s(n,1)+s(n,2)+...+s(n,n)]/n=s(n)=n/2+3/2+2/n(s(0)+s(1)+...+s(n-1))
s(n-1)=(n-1)/2+3/2+2/(n-1)(s(0)+s(1)+...+s(n-2))
ns(n)-(n-1)s(n-1)=n+1+2s(n-1) =>s(n)/(n+1)=s(2)/3+1/3+...+1/n
1+1/2+...+1/n=ln n+O(1) => s(n)=(n+1)ln n +O(n)
二,归并排序
基本思想(链表存储):首先,尽量将链表分为元素数相等的两个子串,然后分别对其排序,递
归分解直到满足终止条件:sub_list=NULL&&sub_list->next=NULL。最后再将两个已排序
的子串合并为一个链表。
<未完待续>