顺序数,order statics,直接翻译是顺序统计,个人觉得不能表达他的意思。实际上它指的是指定集合中的一个数字,这个数字在排序后的集合中占据第i个位置。显然这个数是和顺序相关的,而和统计的关系不大。
特殊的顺序数有最大值,最小值,分别对应第n顺序数和第1顺序数。
选择算法就是求解顺序数的算法:
输入:一个包含n个不同数字的集合,以及一个整数 i 表示第几个顺序数;
输出:第 i 个顺序数。
求最小数和最大数可以在线性时间内完成,求最小的代码如下:
F(p,q)
tmp = A[p];
p++
while(p<=q)
if(tmp<A[p])
tmp=A[p]
p++
return tmp
显然算法复杂度为O(n).
如果需要同时求最大最小,可以通过每次取两个数,其中大的一个和当前最大值比,小的和最小值比,从而可以实现 3*n/2的比较次数。
如果求任意一个顺序数,例如第2个,第3个,那么用比较的方法复杂度较高,而使用快速排序的分区方法复杂度就降低很多。算法如下:
F(p,q,i)
if(p=q) return A[p];
r=partition(p,q)
if(r<i) F(r+1,q,i-r)
else if (r >i) F(p,r-1,i)
else return A[r]
在这个算法中 T(n)=T(k)+T(n-k-1)+O(n)
如果极度不均衡,每次分区的结果一个为0,那么复杂度是n*n。
平均复杂度可以如下计算。
首先,n的复杂度取决于它分成的两个分区的较大的那份。即:
T(n)<= T( max(k-1,n-k))+O(n),O(n)是分区函数的复杂度
利用随机变量X(k)当取到k为1否则为0,那么
T(n)=Sum( X(k)*T( max(k-1, n-k))+O(n)
由于X(k)和T同时发生的概率等于两个的乘法,所以独立。
故E(T(n)=1/n Sum(E (T(k))+o(n)
通过代入法,可得T(n)<cn
因此该算法的平均复杂度是O(n)
通过对上述算法的改良,可以得到最坏复杂度为线性的算法。
1. 首先将输入数组5个分成一组,有k组;
2. 每组求中间数,共k个;
3. 对k个中间数求中间数,x;
4. 对x分区,得到结果r;
5. i小于r在左边分区继续找;i大于r在右边找;
由于每次都会使得3*n/10的数据小于和大于n故最大分区时7*n/10。
因此T(n)=T(n/5)+T(n*7/10)+O(n)
根据代入法,可知结果为线性。
当然上述算法可以扩展,如果只分成3个一组的话,那么每组最大分区是2/3。
因此复杂度为T(n)=T(n/3)+T(2n/3)+O(n)
如果带入T(n)<cn,
T(n)=cn/3+2cn/3+an<cn不能成立。
最后那个输油管道的问题,不知道怎么解决。