排序算法
1 <?php 2 error_reporting(E_ALL); 3 /*=========冒泡排序 bubble sort===========*/ 4 /*以升序为例 */ 5 /*每次比较相邻两个元素,小数往前放,大数往*/ 6 /*后放,一次外围循环完成后最大的数就排在了*/ 7 /*最后边 */ 8 /*========================================*/ 9 function bubble_sort($arr){ 10 if(($len=count($arr))<2){ 11 return $arr; 12 } 13 for($i=0;$i<$len;$i++){ 14 $flag = true; 15 for($j=$len-1;$j>$i;$j--){ 16 if($arr[$j]<$arr[$j-1]){ 17 $arr[$j]=$arr[$j]^$arr[$j-1]; 18 $arr[$j-1]=$arr[$j]^$arr[$j-1]; 19 $arr[$j]=$arr[$j]^$arr[$j-1]; 20 $flag = false; 21 } 22 } 23 //冒泡排序优化 24 if($flag){ 25 break; 26 } 27 } 28 return $arr; 29 } 30 31 /*============quick sort====================*/ 32 /*通过一趟排序将要排序的数据分割成独立的两部*/ 33 /*分,其中一部分的所有数据都比另外一部分的所*/ 34 /*有数据都要小,然后再按此方法对这两部分数据*/ 35 /*分别进行快速排序,整个排序过程可以递归进行*/ 36 /*,以此达到整个数据变成有序序列。 */ 37 /*==========================================*/ 38 function quick_sort($arr){ 39 if(($len=count($arr))<2){ 40 return $arr; 41 } 42 $key = $arr[0]; 43 $left = array(); 44 $right = array(); 45 for($i=1;$i<$len;$i++){ 46 if($arr[$i]>$key){ 47 $right[] = $arr[$i]; 48 }else{ 49 $left[] = $arr[$i]; 50 } 51 } 52 $left = quick_sort($left); 53 $right = quick_sort($right); 54 return array_merge($left,array($key),$right); 55 } 56 57 /*==============select sort=====================*/ 58 /*每一趟从待排序的数据元素中选出最小(或最大)的*/ 59 /*一个元素,顺序放在已排好序的数列的最后,直到全*/ 60 /*部待排序的数据元素排完。选择排序是不稳定的排序*/ 61 /*方法 */ 62 /*==============================================*/ 63 function select_sort($arr){ 64 if(($len=count($arr))<2){ 65 return $arr; 66 } 67 for($i=0;$i<$len-1;$i++){ 68 //每次循环选出最小(或最大)的一个元素 69 //注意每次都是与$arr[$i]进行比较 70 for($j=$i+1;$j<$len;$j++){ 71 if($arr[$j]<$arr[$i]){ 72 $arr[$j]=$arr[$j]^$arr[$i]; 73 $arr[$i]=$arr[$j]^$arr[$i]; 74 $arr[$j]=$arr[$j]^$arr[$i]; 75 } 76 } 77 } 78 return $arr; 79 } 80 81 /*================select sort===============*/ 82 /*优化后的选择排序 */ 83 /*==========================================*/ 84 function select_sort_optimize($arr){ 85 if(($len=count($arr))<2){ 86 return $arr; 87 } 88 for($i=0;$i<$len;$i++){ 89 $min = $i; 90 $flag = 0; 91 for($j=$i+1;$j<$len;$j++){ 92 if($arr[$j]<$arr[$min]){ 93 $min = $j; 94 $flag = 1; 95 } 96 } 97 if($flag){ 98 $arr[$i] = $arr[$i]^$arr[$min]; 99 $arr[$min] = $arr[$i]^$arr[$min]; 100 $arr[$i] = $arr[$i]^$arr[$min]; 101 } 102 } 103 return $arr; 104 } 105 106 /*================insert sort===============*/ 107 /*从第二个元素开始,该元素以前的所有元素可以*/ 108 /*认为已经被排序,取出下一个元素,在已经排序*/ 109 /*的元素序列中从后向前扫描,如果该元素(已排*/ 110 /*序)大于新元素,将该元素移到下一位置,重复*/ 111 /*步骤3,直到找到已排序的元素小于或者等于新 */ 112 /*元素的位置,将新元素插入到下一位置中,重复*/ 113 /*步骤2 */ 114 /*==========================================*/ 115 function insert_sort($arr){ 116 if(($len=count($arr))<2){ 117 return $arr; 118 } 119 for($i=1;$i<$len;$i++){ 120 $temp = $arr[$i]; 121 $j = $i; 122 while($arr[$j-1]>$temp){ 123 //元素后移 124 $arr[$j] = $arr[$j-1]; 125 $j--; 126 if($j<1){ 127 break; 128 } 129 } 130 $arr[$j] = $temp; 131 } 132 return $arr; 133 } 134 135 //应用举例 136 $arr = array(2,1,20,25,10,9,6,7); 137 echo '<pre>'; 138 print_r(bubble_sort($arr)); 139 print_r(quick_sort($arr)); 140 print_r(select_sort($arr)); 141 print_r(select_sort_optimize($arr)); 142 print_r(insert_sort($arr)); 143 echo '</pre>';
合并排序是一个O(nlogn)的算法,其基本思想就是一个分治的策略,先进行划分,然后再进行合并,下面举个例子。
有这样一组数据,{5,4,1,22,12,32,45,21},如果对它进行合并排序的话,首先将它从中间分开,这样,它就被分成了两个数组{5,4,1,22} {12,32,45,21}。
对这两个数组,也分别进行这样的操作,逐步的划分,直到不能再划分为止(每个子数组只剩下一个元素),这样,划分的过程就结束了。
划分的过程如下图所示:
接下来,我们进行合并操作,依照上图,划分过程是从上到下进行的,而合并的过程是从下往上进行的,例如上图中,最下层{5},{4}这两个数组,如 果按升序排列,将他们合并后的数组就是{4,5}。{1},{22}这两个子数组合并后是{1,22}。而{4,5}与{1,22},这两个数组同属一个 分支,他们也需要进行合并,由于这两个子数组本身就是有序的,所以合并的过程就是,每次从待合并的两个子数组中选取一个最小的元素,然后把这个元素放到合 并后的数组中,前面两个数组合并后就是{1,4,5,22}。依次类推,直到合并到最上层结束,这是数据的排序已经完成了。
合并的过程如下图所示。这个过程是从下往上的。
1 <?php 2 /*===============归并排序==================*/ 3 //递归拆分数组并调用合并方法 4 function merge_sort($arr){ 5 if(($len=count($arr))<2){ 6 return $arr; 7 } 8 $mid = floor($len/2); 9 $left = array_slice($arr,0,$mid); 10 $right = array_slice($arr,$mid); 11 return merge(merge_sort($left),merge_sort($right)); 12 } 13 //合并的过程 14 function merge($left,$right){ 15 $result = array(); 16 while(count($left)>0&&count($right)>0){ 17 if($left[0]<$right[0]){ 18 array_push($result,array_shift($left)); 19 }else{ 20 array_push($result,array_shift($right)); 21 } 22 } 23 return array_merge($result,$left,$right); 24 } 25 26 $arr = array(2,1,4,3,8,5,12,7); 27 print_r(merge_sort($arr));