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 smarty截取中文字符乱码问题?gb2312/utf-8
Nov 07 PHP
实例介绍PHP的Reflection反射机制
Aug 05 PHP
php实现的太平洋时间和北京时间互转的自定义函数分享
Aug 19 PHP
ThinkPHP模板输出display用法分析
Nov 26 PHP
Zend Guard使用指南及问题处理
Jan 07 PHP
PHP flush 函数使用注意事项
Aug 26 PHP
php array_keys 返回数组的键名
Oct 25 PHP
自制PHP框架之路由与控制器
May 07 PHP
PHP实现自动发送邮件功能代码(qq 邮箱)
Aug 18 PHP
PHP程序员学习使用Swoole的理由
Jun 24 PHP
PHP asXML()函数讲解
Feb 03 PHP
php 中的信号处理操作实例详解
Mar 04 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
php数组函数序列之in_array() - 查找数组中是否存在指定值
2011/11/07 PHP
深入PHP数据加密详解
2013/06/18 PHP
9段PHP实用功能的代码推荐
2014/10/14 PHP
php常用数学函数汇总
2014/11/21 PHP
Yii2创建表单(ActiveForm)方法详解
2016/07/23 PHP
Dreamweaver jQuery智能提示插件,支持版本提示,支持1.6api
2011/07/31 Javascript
js arguments对象应用介绍
2012/11/28 Javascript
js调用webservice中的方法实现思路及代码
2013/02/25 Javascript
各种页面定时跳转(倒计时跳转)代码总结
2013/10/24 Javascript
js实现鼠标划过给div加透明度的方法
2015/05/25 Javascript
简介BootStrap model弹出框的使用
2016/04/27 Javascript
AngularJS入门(用ng-repeat指令实现循环输出
2016/05/05 Javascript
详解Weex基于Vue2.0开发模板搭建
2017/03/20 Javascript
webpack4.x CommonJS模块化浅析
2018/11/09 Javascript
使用nvm和nrm优化node.js工作流的方法
2019/01/17 Javascript
详解一个基于套接字实现长连接的express
2019/03/28 Javascript
微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】
2019/05/05 Javascript
[03:24]DOTA2超级联赛专访hao 大翻盘就是逆袭
2013/05/24 DOTA
[10:21]2018DOTA2国际邀请赛寻真——Winstrike
2018/08/11 DOTA
wxpython 学习笔记 第一天
2009/03/16 Python
Python yield使用方法示例
2013/12/04 Python
python通过索引遍历列表的方法
2015/05/04 Python
详细解析Python中__init__()方法的高级应用
2015/05/11 Python
基于pandas数据样本行列选取的方法
2018/04/20 Python
tensorflow实现tensor中满足某一条件的数值取出组成新的tensor
2020/01/04 Python
动态设置django的model field的默认值操作步骤
2020/03/30 Python
python实时监控logstash日志代码
2020/04/27 Python
python新手学习可变和不可变对象
2020/06/11 Python
Python 操作 MySQL数据库
2020/09/18 Python
LightInTheBox法国站:中国跨境电商
2020/03/05 全球购物
通往英国高街的商店橱窗:Down Your High Street
2020/07/19 全球购物
从事会计工作年限证明
2015/06/23 职场文书
《彼得与狼》教学反思
2016/02/20 职场文书
2019大学生实习报告
2019/06/21 职场文书
学生早退检讨书(范文)
2019/08/19 职场文书
HTML中link标签属性的具体用法
2023/05/07 HTML / CSS