我是正常蛇

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Order Statistic:

The ith smallest of n elements.(i from 1 to n).

 

Median:

The [n/2]th smallest of n elements.

Here we all talk about value , not key.

 

How to find the ith smallest number in a part of a array?

Steps:

1) Call the function partition which I have written down in quick sort chapter.Get the position of a random guy we called "pivot".

2) Cause the left part of the array by pivot is all less than pivot,and right part is larger than it,now assume a = the number of the left part elements + 1 ,so pivot is actually the ath smallest in this array.

3) Compare a with i,if equal then return array[i], if a > i , then we do this job again for the smaller part ,which is left of ,the array,and if a < i we do the larger part.

Performance:

T(n) = Θ(n).

Some codes:

 1 function partition($a,$p,$q)
 2 {
 3     $pivot = $a[$p];
 4     if(count($a) == 1) return $a;
 5     for($i = -1,$j = 0,$k = $q; $j < $k; $j++)
 6     {
 7         if($a[$j] <= $pivot)
 8         {
 9             $i++;
10             $buf = $a[$j];
11             $a[$j] = $a[$i];
12             $a[$i] = $buf;
13         }
14     }
15     $a[$p] = $a[$i];
16     $a[$i] = $pivot;
17     return $i;
18 }
19 
20 function randomizedSelect($a,$p,$q,$r)
21 {
22     if($p == $q) return $a[$p];
23     $i = partition(&$a,$p,$q);
24     $k = $i - $p + 1;    
25     if($k == $r)
26     {
27         return $a[$i];
28     }
29     if($k < $r)
30         return randomizedSelect(&$a,$i + 1,$q,$r - $k);
31     else
32         return randomizedSelect(&$a,$p,$i-1,$r);
33 }

 

 Here is another algorithm that is the worst case linear time randomized select. 

Steps:

1) Divide the input array into several subarrays by length 5.

2) Search for the medians of each subarray by insersion search.

3) Search for the median of the bunch of medians by recurrency. And that is our pivot.

4) Run the partition algorithm with the specified pivot to get the kth smallest number.

5) compare with the k and our expected r.

 

Here are my php codes of this algorithem, but something goes wrong and the result is a mess. I'd really appreciate it if somebody helps me out.

function partitionWithPivot($a,$p,$q,$pivot)
{
    if(count($a) == 1) return 1;
    $i = $p - 1;
    for($j = $p,$k = $q; $j < $k; $j++)
    {
        if($a[$j] <= $pivot)
        {
            $i++;
            $buf = $a[$j];
            $a[$j] = $a[$i];
            $a[$i] = $buf;
        }
    }
    return $i + 1;
}


function goodPivotRandomizedSelect($a,$p,$q,$r)
{
    global $count;
    $count++;
    if($count == 2000)
    {
        echo "too many recurrency";
        exit;
    }
    if($p == $q)
    {
        return $a[$p];
    }
    $midHolder = array();
    for($i = $p; $i <= $q - $p; $i = $i + 5)
    {
        $buf = array();
        for($j = 0; $j <5 ; $j++)
        {
            if(isset($a[$i+$j]))
                $buf[] = $a[$i+$j];
        }
        insersionSort(&$buf);
        $midHolder[] = $buf[intval(count($buf)/2)];
    }
    $pivot = goodPivotRandomizedSelect($midHolder,0,count($midHolder) - 1,(int)(count($midHolder)/2));
    $mid = partitionWithPivot(&$a,$p,$q,$pivot);
    $k = $mid - $p + 1;
    if($k == $r)
        return $a[$mid];
    if($k < $r)
        return goodPivotRandomizedSelect($a,$mid + 1,$q,$r - $k);
    else
        return goodPivotRandomizedSelect($a,$p,$mid - 1,$r);

}

 

 

 

 

posted on 2012-09-04 15:00  我是正常蛇  阅读(654)  评论(0编辑  收藏  举报