php语言的7种基本的排序方法


Posted in PHP onDecember 28, 2020

本文总结了一下常用的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;
}

使用经验

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

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

PHP 相关文章推荐
php扩展ZF――Validate扩展
Jan 10 PHP
php 数组的合并、拆分、区别取值函数集
Feb 15 PHP
PHP排序算法的复习和总结
Feb 15 PHP
js和php邮箱地址验证的实现方法
Jan 09 PHP
php实现数组筛选奇数和偶数示例
Apr 11 PHP
PHP错误Cannot use object of type stdClass as array in错误的解决办法
Jun 12 PHP
javascript数组与php数组的地址传递及值传递用法实例
Jan 22 PHP
php生成RSS订阅的方法
Feb 13 PHP
php简单实现单态设计模式的方法分析
Jul 28 PHP
PHP 传输会话curl函数的实例详解
Sep 12 PHP
laravel 数据迁移与 Eloquent ORM的实现方法
Apr 12 PHP
Laravel重定向,a链接跳转,控制器跳转示例
Oct 22 PHP
php实现图片上传并利用ImageMagick生成缩略图
Mar 14 #PHP
YII Framework框架教程之国际化实现方法
Mar 14 #PHP
YII Framework框架教程之缓存用法详解
Mar 14 #PHP
YII Framework框架教程之安全方案详解
Mar 14 #PHP
YII Framework框架教程之日志用法详解
Mar 14 #PHP
YII Framework教程之异常处理详解
Mar 14 #PHP
Zend Framework教程之Application用法实例详解
Mar 14 #PHP
You might like
第十三节--对象串行化
2006/11/16 PHP
php 开发中加密的几种方法总结
2017/03/22 PHP
select 控制网页内容隐藏于显示的实现代码
2010/05/25 Javascript
JavaScript高级程序设计(第3版)学习笔记5 js语句
2012/10/11 Javascript
javascript:;与javascript:void(0)使用介绍
2013/06/05 Javascript
Javascript中判断变量是数组还是对象(array还是object)
2013/08/14 Javascript
javascript Array.prototype.slice的使用示例
2013/11/14 Javascript
javascript实现滑动解锁功能
2014/12/31 Javascript
Javascript基础教程之switch语句
2015/01/18 Javascript
js随机生成字母数字组合的字符串 随机动画数字
2015/09/02 Javascript
详解Javascript中prototype属性(推荐)
2016/09/03 Javascript
Swiper实现轮播图效果
2017/07/03 Javascript
create-react-app 修改为多入口编译的方法
2018/08/01 Javascript
Javascript查看大图功能代码实现
2020/05/07 Javascript
[03:06]V社市场总监Dota2项目负责人Erik专访:希望更多中国玩家加入DOTA2
2014/07/11 DOTA
Python找出list中最常出现元素的方法
2016/06/14 Python
Python实现PS滤镜Fish lens图像扭曲效果示例
2018/01/29 Python
用PyInstaller把Python代码打包成单个独立的exe可执行文件
2018/05/26 Python
解决python 3 urllib 没有 urlencode 属性的问题
2019/08/22 Python
Django admin 实现search_fields精确查询实例
2020/03/30 Python
PyCharm+Pipenv虚拟环境开发和依赖管理的教程详解
2020/04/16 Python
英国IT硬件供应商,定制游戏PC:Mesh Computers
2019/03/28 全球购物
Coccinelle官网:意大利的著名皮具品牌
2019/05/15 全球购物
联强国际笔试题面试题
2013/07/10 面试题
小学生自我鉴定
2013/10/12 职场文书
国际贸易专业推荐信
2013/11/15 职场文书
汽车销售顾问求职自荐信
2014/01/01 职场文书
高一新生军训感言
2014/03/02 职场文书
信息技术毕业生自荐信范文
2014/03/13 职场文书
双语教学实施方案
2014/03/23 职场文书
考试作弊检讨书1000字(5篇)
2014/10/19 职场文书
2014年房地产销售工作总结
2014/12/01 职场文书
基于nginx实现上游服务器动态自动上下线无需reload的实现方法
2021/03/31 Servers
如何用 Python 子进程关闭 Excel 自动化中的弹窗
2021/05/07 Python
MySql学习笔记之事务隔离级别详解
2021/05/12 MySQL
Win10系统搭建ftp文件服务器详细教程
2022/08/05 Servers