《算法导论》第九章.中位数和顺序统计量
一.什么是中位数?
在一个n个元素顺序排列的集合中,一个中位数是它所属集合的中点元素。
用公式表达中位数的位置就是:
1.当n为奇数时:
i=(n+1)/2;
2.当n为偶数时,有两个中位数:
i=n/2 ;
i=n/2+1;
因此,若不考虑n的奇偶性,中位数总是出现在 :i=(n+1)/2处和i=(n+2)/2处。
为了方便起见,以后博客的内容默认中位数在:(n+1)/2处
二.本章主要内容:
本章将讨论从一个有由n个互不相同的元素组成的集合中选择第i个顺序统计量(就是在顺序的排序的下第i个元素)的问题。
于是我们可以对输入和输出有如下的定义:
输入:一个包含n个数的集合A和一个整数i,1<=i<=n。
输出:元素x,且在A中恰好有i-1个小于它的元素。
我们很容易的知道可以通过排序算法将数组A排个序,然后找出第i个元素就可以解决这个问题。但是有没有更快的算法呢?
当然有,这个就是本章的内容。
三.具体策略:
1.特例:最小值和最大值
我们要知道:如果我们为了确定n个元素中的最小值或最大值,必须要做n-1次比较。
那么如果我们要同时确定最大值和最小值,就一定要进行2n-2次比较吗?
事实上,我们有只需要3n/2次比较就可以同时找到最大值和最小值的方法!!
做法如下:
(1)首先,我们将一对输入元素相互进行比较
(2)然后把较小的与当前最小值比较,把最大的与当前最大值进行比较。
这样,对每两个元素共需三次比较。
那么如何设定当前的最小值和最大值呢?
这个取决于n是奇数还是偶数:如果n是奇数,最大值最小值都是第一个元素。
如果n是偶数,就对前两个元素做一次比较来决定最大值最小值。
算法java代码实现:
public class MinAMax {
int max;
int min;
public void MaxMin(int a[]){
if(a.length%2==1){
//如果数组a中元素有奇数个
max=min=a[0];//将第一个元素默认为最大值和最小值
for(int i=1;i<a.length;i+=2) {
//从第二个元素开始成对向后循环,直到结束
if(a[i]>a[i+1])//比较两个元素,如果前者大于后者,互换
Swap(a,i,i+1);
if(a[i]<min)//将较小者与当前最小值比较
min=a[i];
if(a[i+1]>max)//将较大者与当前最大值比较