zoukankan      html  css  js  c++  java
  • 排序算法之归并排序

      归并排序是成功应用分治技术的一个完美例子。

      分治法的思想是:(1)将问题的实例划分为同一个问题的几个较小的实例,最好拥有同样的规模;(2)对这些较小的实例求解(一般用递归方法,但在问题规模足够小的时候。有时也会利用另一个算法);(3)如果必要的话,合并这些较小问题的解,以得到原始问题的解。

      对于一个需要排序的数组$a[0...n-1],归并排序把它一分为二:$a[0..n/2-1]和$a[n/2...n-1],并对每个子数组递归排序,然后把这两个排好序的子数组合并为一个有序数组。

      下面的这个图能够很好地解释归并排序的整个流程(自己画的,有点丑)。

          

      看上面的图,我们就知道了。递归的将一个数组分成两部分,直到小的足以解决问题就不再递归(一个数,一定是有序的)。然后再将两个有序的数组合并,最后整个数组就是有序的了。

      算法如下:

     1 <?php
     2     /**
     3      * 归并排序
     4      * 递归调用mergeSort来对数组$a排序
     5      * @param $a 一个可排序的数组
     6      * @return $a 非降序排列的数组
     7      */
     8     function mergeSort(&$a){
     9         $t = count($a);
    10         if($t<=1){
    11             return;
    12         }
    13         $b = array_slice($a, 0, intval($t/2));
    14         $c = array_slice($a, intval($t/2));
    15             
    16         /* echo '<br/>$b: ';
    17         print_r($b);
    18         echo '<br/>$c: ';
    19         print_r($c); */
    20             
    21         mergeSort($b);
    22         mergeSort($c);
    23         merge($b, $c, $a);
    24             
    25         /* echo "<br/>".'$a: ';
    26         print_r($a);
    27         echo "<br/>"; */
    28     }
    29     /**
    30      * 将两个有序数组$y, $z合并为一个有序数组$x
    31      * @param $y, $z, $x
    32      * @return $x
    33     */
    34     function merge(&$y, &$z, &$x){
    35         $i = $j = $k = 0;
    36         $p = count($y);
    37         $q = count($z);
    38         while($i<$p && $j<$q){
    39             if($y[$i]<$z[$j]){
    40                 $x[$k] = $y[$i];
    41                 $i++;
    42             }else{
    43                 $x[$k] = $z[$j];
    44                 $j++;
    45             }
    46             $k++;
    47         }
    48         if($i==$p){
    49             while($j<$q){
    50                 $x[$k] = $z[$j];
    51                 $j++;
    52                 $k++;
    53             }
    54         }else{
    55             while($i<$p){
    56                 $x[$k] = $y[$i];
    57                 $i++;
    58                 $k++;
    59             }
    60         }
    61     }
    62 ?>

      如果想看中间的输出结果,只需要把mergeSort()中的注释去掉就可以了。

      归并排序与快排相比,归并排序是规定的排序,这对要排序数据包含多个信息而要按其中的某一个信息排序,要求其他信息尽量按输入的顺序排列很重要,这也是它比快排有优势的地方。

  • 相关阅读:
    VIM 配色方案,先保存一下
    ncurses库的介绍与安装
    win7 设置双屏壁纸
    3. Vim入门教程
    2. Vim 概念扫盲
    把Debian 设置中文环境
    静态代码块和构造代码块的区别
    jsp详解(3个指令、6个动作、9个内置对象、11个隐式对象)
    JVM虚拟机详解
    Java 的内置对象
  • 原文地址:https://www.cnblogs.com/xumengxuan/p/2801070.html
Copyright © 2011-2022 走看看