7种php基本排序实现方法

本文总结了一下常用的7种排序方法,并用php语言实现。

1、直接插入排序

/*
 *  直接插入排序,插入排序的思想是:当前插入位置之前的元素有序,
 *  若插入当前位置的元素比有序元素最后一个元素大,则什么也不做,
 *  否则在有序序列中找到插入的位置,并插入
 */
function insertSort($arr) {
  $len = count($arr);
  for($i = 1; $i < $len; $i++) {
    if($arr[$i-1] > $arr[i]) {
      for($j = $i - 1;$j >= 0; $j-- ) {
        $tmp = $arr[$j+1];
        if($tmp < $arr[$j]) {
          $arr[$j+1] = $arr[$j];
          $arr[$j] = $tmp;
        }else{
          break;
        }
      }
    }
  }
  return $arr;
}

2、冒泡排序

/*
  冒泡排序,冒泡排序思想:进行 n-1 趟冒泡排序, 每趟两两比较调整最大值到数组(子数组)末尾
*/
function bubbleSort($arr) {
  $len = count($arr);
  for($i = 1; $i < $len; $i++) {
    for($j = 0; $j < $len-$i; $j++) {
      if($arr[$j] > $arr[$j+1]) {
        $tmp = $arr[$j+1];
        $arr[$j+1] = $arr[$j];
        $arr[$j] = $tmp;
      }
    }
  }
  return $arr;
}

3、简单选择排序

/*
  简单选择排序, 简单排序思想:从数组第一个元素开始依次确定从小到大的元素
*/
function selectSort($arr) {
  $len = count($arr);
  for($i = 0; $i < $len; $i++) {
    $k = $i;
    for($j = $i+1; $j < $len; $j++) {
      if($arr[$k] > $arr[$j]) {
        $k = $j;
      }
    }
    if($k != $i) {
      $tmp = $arr[$i];
      $arr[$i] = $arr[$k];
      $arr[$k] = $tmp;
    }
  }
  return $arr;
}

4、希尔排序

/*
  希尔排序,希尔排序原理:将数组按指定步长分隔成若干子序列,然后分别对子序列进行排序(在这是直接)
*/
function shellSort($arr) {
  $len = count($arr);
  $k = floor($len/2);
  while($k > 0) {
    for($i = 0; $i < $k; $i++) {
      for($j = $i; $j < $len, ($j + $k) < $len; $j = $j + $k) {
        if($arr[$j] > $arr[$j+$k]) {
          $tmp = $arr[$j+$k];
          $arr[$j+$k] = $arr[$j];
          $arr[$j] = $tmp;
        }
      }
    }
    $k = floor($k/2);
  }
  return $arr;
}

5、快速排序

/*
 *  快速排序,快排思想:通过一趟排序将待排的记录分为两个独立的部分,其中一部分的记录的关键字均不大于
 *  另一部分记录的关键字,然后再分别对这两部分记录继续进行快速排序,以达到整个序列有序,具体做法需要
 *  每趟排序设置一个标准关键字和分别指向头一个记录的关键字和最后一个记录的关键字的指针。
 *  quickSort($arr, 0, count($arr) -1);
 */
function quickSort(&$arr,$low,$high) {
  if($low < $high) {
    $i = $low;
    $j = $high;
    $primary = $arr[$low];
    while($i < $j) {
      while($i < $j && $arr[$j] >= $primary) {
        $j--;
      }
      if($i < $j) {
        $arr[$i++] = $arr[$j];
      }
      while($i < $j && $arr[$i] <= $primary) {
        $i++;
      }
      if($i < $j) {
        $arr[$j--] = $arr[$i];
      }
    }
    $arr[$i] = $primary;
    quickSort($arr, $low, $i-1);
    quickSort($arr, $i+1, $high);
  }
}

6、堆排序

/*
  堆排序
*/

// 调整子堆的为大根堆的过程,$s为子堆的根的位置,$m为堆最后一个元素位置
function heapAdjust(&$arr, $s, $m) {
  $tmp = $arr[$s];
  // 在调整为大根堆的过程中可能会影响左子堆或右子堆
  // for循环的作用是要保证子堆也是大根堆
  for($j = 2*$s + 1; $j <= $m; $j = 2*$j + 1) {
    // 找到根节点的左右孩子中的最大者,然后用这个最大者与根节点比较,
    // 若大则进行调整,否则符合大根堆的 特点跳出循环
    if($j < $m && $arr[$j] < $arr[$j+1]) {
      $j++;
    }
    if($tmp >= $arr[$j] ) {
      break;
    }
    $arr[$s] = $arr[$j];
    $s = $j;
  }
  $arr[$s] = $tmp;
}

// 堆排序
function heapSort($arr) {
  $len = count($arr);
  // 依次从子堆开始调整堆为大根堆
  for($i = floor($len/2-1); $i >= 0; $i--) {
    heapAdjust($arr, $i, $len-1);
  }
  // 依次把根节点调换至最后一个位置,再次调整堆为大根堆,找到次最大值,
  // 依次类推得到一个有序数组
  for($n = $len-1; $n > 0; $n--) {
    $tmp = $arr[$n];
    $arr[$n] = $arr[0];
    $arr[0] = $tmp;
    heapAdjust($arr, 0, $n-1);
  }
  return $arr;
}

7、归并排序

/*
  归并排序,这里实现的是两路归并
*/
// 分别将有序的$arr1[s..m]、$arr2[m+1..n]归并为有序的$arr2[s..n]
function Merge(&$arr1, &$arr2, $s, $m, $n) {
  for($k = $s,$i = $s, $j = $m+1; $i <= $m && $j <= $n; $k++) {
    if($arr1[$i]<$arr1[$j]) {
      $arr2[$k] = $arr1[$i++];
    }else {
      $arr2[$k] = $arr1[$j++];
    }
  }
  if($i <= $m) {
    for(; $i <= $m; $i++) {
      $arr2[$k++] = $arr1[$i];
    }
  } else if($j <= $n) {
    for(; $j <= $n; $j++) {
      $arr2[$k++] = $arr1[$j];
    }
  }
}

// 递归形式的两路归并
function MSort(&$arr1, &$arr2, $s, $t) {
  if($s == $t) {
    $arr2[$s] = $arr1[$s];
  }else {
    $m = floor(($s+$t)/2);
    $tmp_arr = array();
    MSort($arr1, $tmp_arr, $s, $m);
    MSort($arr1, $tmp_arr, $m+1, $t);
    Merge($tmp_arr, $arr2, $s, $m, $t);
  }
}

// 对一位数组$arr[0..n-1]中的元素进行两路归并
function mergeSort($arr) {
  $len = count($arr);
  MSort($arr, $arr, 0, $len-1);
  return $arr;
}

使用经验
若排序的记录数目n较小时,可以采用直接插入排序和简单选择排序,当记录本身信息量较大时,用简单选择排序方法较好。
若待排序记录按关键字基本有序,适合采用直接插入排序和冒泡排序。
若n值较大时,可以采用快速排序、堆排序和归并排序。另外快速排序被认为是内部排序方法中最好的方法。

以上就是本文的全部内容,希望对大家的学习有所帮助。

(0)

相关推荐

  • PHP二维数组排序的3种方法和自定义函数分享

    关于排序一般我们都是通过数据库或者nosql(eg:redis)先排好序然后输出到程序里直接使用,但是有些时候我们需要通过PHP直接来对数组进行排序,而在PHP里存储数据用到最多的就是对象和数组,但处理较多的就是数组,因为有非常丰富的内置函数库(其实对象一定程度上也可以理解为是数组),这些函数库很大程度上可以帮助我们实现某些功能.常用的系统函数有sort.asort.arsort.ksort.krsort等等,这里我主要说下对二维数组的排序,两种方法: 一.用PHP自带array_multiso

  • php中多维数组按指定value排序的实现代码

    呵呵,业务需要按多维数组中某个元素进行排序,在PHP中也是非常容易实现的,一个函数调用一个回调函数就搞定了.贴出代码: 复制代码 代码如下: $arr = array( 'index'=>array( 'name'=>'首页','order'=>3), 'intro'=>array( 'name'=>'企业概况','order'=>2), 'news'=>array( 'name'=>'新闻动态','order'=>1 ), 'product'=>

  • php二维数组排序详解

    有时候为了达到一定目的,需要对二维数组进行排序,现分享一下其实现的方法. 复制代码 代码如下: $arr=array ('1' => array ( 'date' => '2011-08-18', 'num' => 5 ) ,'2' => array ( 'date' => '2011-08-20', 'num' => 3 ) ,'3' => array ( 'date' => '2011-08-17', 'num' => 10 ) )  ; $res

  • php数组中包含中文的排序方法

    php数组中文排序,文件格式一般用utf8,直接用asort排序不行.若是gbk和gb2312可以.这跟编码有关.gbk和gb2312本身的编码就是用拼音排序的. 复制代码 代码如下: function utf8_array_asort(&$array) {if(!isset($array) || !is_array($array)) {  return false;}foreach($array as $k=>$v) {  $array[$k] = iconv('UTF-8', 'GB23

  • php二维数组排序方法(array_multisort usort)

    例如像下面的数组: 复制代码 代码如下: $users = array(    array('name' => 'tom', 'age' => 20)    , array('name' => 'anny', 'age' => 18)    , array('name' => 'jack', 'age' => 22)); 希望能按照age从小到大进行排序.笔者整理了两个方法出来,分享给大家. 1.使用array_multisort 使用这个方法,会比较麻烦些,要将age

  • PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析

    sort() 函数用于对数组单元从低到高进行排序. rsort() 函数用于对数组单元从高到低进行排序. asort() 函数用于对数组单元从低到高进行排序并保持索引关系. arsort() 函数用于对数组单元从高到低进行排序并保持索引关系. ksort() 函数用于对数组单元按照键名从低到高进行排序. krsort() 函数用于对数组单元按照键名从高到低进行排序. sort() PHP sort() 函数用于对数组单元从低到高进行排序,如果成功则返回 TRUE,失败则返回 FALSE. 注意:

  • PHP 多维数组的排序问题 根据二维数组中某个项排序

    PHP内置函数 array_multisort 要求每个数组大小一样 $areas是地区的二维数组,包含人数和次数,现在要按这2种数进行降序排序 复制代码 代码如下: foreach($areaArray as &$areas) { $times = $numbers = array(); foreach($areas as $province => $v) { $times[$province] = $v['times']; $numbers[$province] = $v['number

  • PHP 数组排序方法总结 推荐收藏

    随着PHP的快速发展,用它的人越来越多,在PHP数组学习摘录部分了解到最基本的PHP数组的建立和数组元素的显示.需要深入学习下PHP数组的相关操作.首先接触的就是PHP数组排序.降序的排序问题. sort:本函数为 array 中的单元赋予新的键名.这将删除原有的键名而不仅是重新排序. rsort:本函数对数组进行逆向排序(最高到最低). 删除原有的键名而不仅是重新排序. asort:对数组进行排序并保持索引关系 arsort:对数组进行逆向排序并保持索引关系 ksort:对数组按照键名排序,保

  • php实现快速排序的三种方法分享

    写了三种php快速排示例,第一种效率低但最简单最容易理解,第二个是算法导论上提供的单向一次遍历找中值方法,第三种是双向遍历找中值经典快排算法.三组算法实现和比较如下: 方法一:该方法比较直观,但损失了大量的空间为代价,使用了效率较低的merge函数.在三种方法中效率最低.最坏情况下算法退化为(O(n*n)) 复制代码 代码如下: function quick_sort($array) { if(count($array) <= 1) return $array; $key = $array[0]

  • PHP 冒泡排序 二分查找 顺序查找 二维数组排序算法函数的详解

    数据结构很重要,算法+数据结构+文档=程序使用PHP描述冒泡排序算法,对象可以是一个数组 复制代码 代码如下: //冒泡排序(数组排序)function bubble_sort($array) {$count = count($array);if ($count <= 0)return false;for($i=0; $i<$count; $i++){for($j=$count-1; $j>$i; $j–){if ($array[$j] < $array[$j-1]){$tmp =

随机推荐