1 <?php 2 #随机选择第i小的数字,用随机快排实现 3 4 #交换元素 5 function swap(&$arr, $i, $j) { 6 $temp = $arr[$i]; 7 $arr[$i] = $arr[$j]; 8 $arr[$j] = $temp; 9 } 10 11 #随机划分 12 function randomized_partition(&$arr, $begin, $end) { 13 $rand_inx = rand($begin, $end); 14 swap($arr, $begin, $rand_inx); 15 return partition($arr, $begin, $end); 16 } 17 18 #划分 19 function partition(&$arr, $begin, $end) { 20 #以第一个元素作为中枢元素 21 $pivot = $begin; 22 $low = $begin; 23 $high = $end; 24 25 while ($low < $high) { 26 while ($low < $high && $arr[$low] <= $arr[$pivot]) { 27 $low++; 28 } 29 30 while ($low < $high && $arr[$high] >= $arr[$pivot]) { 31 $high--; 32 } 33 34 swap($arr, $low, $high); 35 } 36 37 #交换中枢元素 38 if ($arr[$pivot] < $arr[$low]) { 39 $low--; 40 } 41 swap($arr, $pivot, $low); 42 return $low; 43 } 44 45 #快速排序,此处没用到 46 function quick_sort(&$arr, $begin, $end) { 47 $q = randomized_partition($arr, $begin, $end); 48 if ($q > $begin) { 49 quick_sort($arr, $begin, $q - 1); 50 } 51 if ($q < $end) { 52 quick_sort($arr, $q + 1, $end); 53 } 54 } 55 56 #选取第i小的数 57 function randomized_select(&$arr, $begin, $end, $i) { 58 if ($begin == $end) { 59 return $arr[$begin]; 60 } 61 62 $q = randomized_partition($arr, $begin, $end); 63 $k = $q - $begin + 1; #k代表小于等于q的元素个数 64 65 if ($k == $i) { #如果k=i,说明q就是第i小的元素坐标 66 return $arr[$q]; 67 } else if ($i < $k) { #如果i<k,说明第i小的元素位于q的左边 68 return randomized_select($arr, $begin, $q - 1, $i); 69 } else { #第i小的元素位于q的右边,此时查找右边的第i-k小的元素 70 return randomized_select($arr, $q + 1, $end, $i - $k); 71 } 72 } 73 74 $arr = array(1, 5, 3, 7, 0, 0, 8, 4, 2, 9, 11); 75 $t = randomized_select($arr, 0, count($arr) - 1, 8); 76 print_r("The 8th minimum element: {$t}"); 77 echo "<br>"; 78 quick_sort($arr, 0, count($arr) - 1); 79 print_r($arr); 80 ?>
The 8th minimum element: 7
Array ( [0] => 0 [1] => 0 [2] => 1 [3] => 2 [4] => 3 [5] => 4 [6] => 5 [7] => 7 [8] => 8 [9] => 9 [10] => 11 )