归并排序的原理是把原始数组分成若干子数组(两两分组),对每一个子数组进行排序,继续把子数组与子数组合并(方法:从两子数组头各取一值,小者放入新数组尾部,大者保留至下一趟对比,直至这两个子数组值全部取完),合并后仍然有序,直到全部合并完,形成有序的数组。
算法示意图:
PHP代码实现参考:
/** * 归并排序 * 原理:把原始数组分成若干子数组(向下递归到2个或1个元素一组),对每一个子数组进行排序, * 继续把子数组与子数组合并(通过取两数组头),合并后仍然有序,直到全部合并完,形成有序的数组 * @param unknown $arr * @return unknown */ function merge_sort($arr){ // 提取法排序后,合并分组 function do_merge_sort(&$arr,$start,$mid,$end){ if($start==$end)return; // 新建一个数据用于存放2段数组中提取出来的有序数据 $sorted_arr = []; // 分别从2段数列中提取首个元素对比 $i = $start; $j = $mid+1; while ( $i<=$mid && $j<=$end ) { if( $arr[$i]<=$arr[$j] ){ $sorted_arr[] = $arr[$i++]; }else{ $sorted_arr[] = $arr[$j++]; } } // 将2段数据中剩余的数据添加的有序数列尾部 while ($i<=$mid) $sorted_arr[] = $arr[$i++]; while ($j<=$end) $sorted_arr[] = $arr[$j++]; // 用有序数列替换掉当前段数据 foreach ($sorted_arr as $v){ $arr[$start++] = $v; } } // 拆分分组,再合并 function do_merge_group(&$arr,$start,$end){ $mid = floor( ($start + $end)/2 ); if( $end-$start>1 ){ // 将数列两两拆分 // 递归拆分排序,直到无法再拆分 do_merge_group($arr,$start,$mid); do_merge_group($arr,$mid+1,$end); } // (将拆分到底层的 或 到底层后合并排序过的数据段)合并排序 do_merge_sort($arr,$start,$mid,$end); } do_merge_group($arr,0,count($arr)-1); return $arr; }
参考:
http://www.cnblogs.com/kkun/archive/2011/11/23/2260271.html
https://www.cnblogs.com/chengxiao/p/6194356.html