您的位置:首页 > 其它

算法导论学习笔记-第9章 中位数和顺序统计学

2010-08-16 21:48 323 查看
在一个由n个元素组成的集合中,第i个顺序统计量是该集合中第i小的元素。

9.1 最小值和最大值

找最小值:依次查看集合中的每个元素,并记录比较过程中的最小元素。

MINIMUM(A)
min = A[1]
for i=2 to length[A]
do if min > A[i]
then min = A[i]
return min


同时找出最小值和最大值:先将一对输入元素互相比较,然后把较小者与当前最小值比较,把较大者与当前最大值比较,因此每两个元素需要3次比较,总的比较次数为3[n/2]。

#include <stdio.h>
void min_max(int a[],int n,int *pmin,int *pmax)
{
int i;
if (n & 1) //n is odd
{
*pmin = *pmax = a[0];
i = 1;
}
else 	//n is even
{
if(a[0] < a[1])
{
*pmin = a[0];
*pmax = a[1];
}
else
{
*pmin = a[1];
*pmax = a[0];
}
i = 2;
}
for(; i < n - 1; i+=2)
{
if(a[i] < a[i + 1])
{
if(a[i] < *pmin)
*pmin = a[i];
if(a[i + 1] > *pmax)
*pmax = a[i + 1];
}
else
{
if(a[i] > *pmax)
*pmax = a[i];
if(a[i + 1] < *pmin)
*pmin = a[i + 1];
}
}
}
int main()
{
int a[] = {4,5,7,1,2,4,3,8,8,9,10,3,12,2,14};
int n = 15;
int min,max;
min_max(a,n,&min,&max);
printf("min = %d/nmax = %d/n",min,max);
return 0;
}


9.2 以期望线性时间做选择

分治算法RANDOMIZED-SELECT:以快速排序算法为模型,对输入数组进行递归划分。和快速排序不同的是,快速排序会递归处理划分的两边,而RANDOMIZED-SELECT只处理划分的一边。

RANDOMIZED-SELECT(A,p,r,i)
if p=r
then return A[p]
q = RANDOMIZED-PARTITION(A,p,r)
k = q-p+1
if i=k
then return A[q]
elseif i
then return RANDOMIZED-SELECT(A,p,q-1,i)
else
return RANDOMIZED-SELECT(A,q+1,r,i-k)


C代码:

#include <stdio.h>
void swap(int *x ,int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int partition(int a[],int p,int r)
{
int x = a[r];
int i = p - 1;
int j;
for(j = p; j < r; j++)
{
if(a[j] <= x)
{
i++;
swap(&a[i],&a[j]);
}
}
swap(&a[i+1],&a[r]);
return i+1;
}
int select(int a[],int p,int r,int i)
{
int q,k;
if(p == r)
return a[p];
q = partition(a,p,r);
k = q - p + 1;
if(i == k)
return a[q];
else if(i < k)
return select(a,p,q-1,i);
else
return select(a,q+1,r,i-k);
}
int main()
{
int a[] = {13,19,9,5,12,8,7,21,2,6,11,4};
int size = 12;
int i;
int key;
for(i = 0; i < size; i++)
printf(" %d",a[i]);
printf("/n");
key = select(a,0,size-1,1);
printf("%d/n",key);

return 0;
}


最坏情况运行时间为θ(n^2),平均情况为O(n)。

9.3 最坏情况线性时间的选择

选择算法SELECT,最坏情况运行时间为O(n)。该算法的基本思想是在RANDOMIZED-SELECT基础上,保证每次对数组的划分都是个好的划分。

执行步骤:

1)将输入数组的n个元素划分为n/5组,每组5个元素,且至多只有一个组由剩下的n mod 5个元素组成。

2)寻找n/5个组中每一个组的中位数。

3)对第2步中找出的n/5个中位数,递归调用SELECT以找出其中位数x。

4)按中位数x对输入数组进行划分。

该算法也被称为 Median of Medians algorithm。当按照该算法找出中位数的中位数x后,可以保证至少有30%个元素小于x,有30%个元素大于等于x。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: