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与已存在的Java应用程序集成
Oct 09 PHP
php date()日期时间函数详解
May 16 PHP
php用数组返回无限分类的列表数据的代码
Aug 08 PHP
PHP对象Object的概念 介绍
Jun 14 PHP
PHP获取当前页面完整URL的实现代码
Jun 10 PHP
完美解决令人抓狂的zend studio 7代码提示(content Assist)速度慢的问题
Jun 20 PHP
简单说说PHP优化那些事(经验分享)
Nov 27 PHP
Yii模型操作之criteria查找数据库的方法
Jul 15 PHP
PHP+MySQL高并发加锁事务处理问题解决方法
Apr 30 PHP
php实现微信公众平台发红包功能
Jun 14 PHP
PHP随机数函数rand()与mt_rand()的讲解
Mar 25 PHP
PHP的静态方法与普通方法用法实例分析
Sep 26 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 配置后台登录以及模板引入
2017/01/24 PHP
PHP批量删除jQuery操作
2017/07/23 PHP
Laravel6.18.19如何优雅的切换发件账户
2020/06/14 PHP
javascript实现上传图片前的预览(TX的面试题)
2007/08/20 Javascript
Javascript 去除数组的重复元素
2010/05/04 Javascript
微博@符号的用户名提示效果。(想@到谁?)
2010/11/05 Javascript
用Mootools获得操作索引的两种方法分享
2011/12/12 Javascript
angular.foreach 循环方法使用指南
2015/01/06 Javascript
javascript实现状态栏文字首尾相接循环滚动的方法
2015/07/22 Javascript
AngularJS基础 ng-repeat 指令简单示例
2016/08/03 Javascript
JS简单实现无缝滚动效果实例
2016/08/24 Javascript
vue.js父组件使用外部对象的方法示例
2017/04/25 Javascript
解决element-ui的下拉框有值却无法选中的情况
2020/11/07 Javascript
[01:07:20]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第二场 2月2日
2021/03/11 DOTA
Python实现partial改变方法默认参数
2014/08/18 Python
Python中对列表排序实例
2015/01/04 Python
Python实现多线程HTTP下载器示例
2017/02/11 Python
python使用标准库根据进程名如何获取进程的pid详解
2017/10/31 Python
selenium+python自动化测试之页面元素定位
2019/01/23 Python
详解Python3 基本数据类型
2019/04/19 Python
用pyqt5 给按钮设置图标和css样式的方法
2019/06/24 Python
Django框架model模型对象验证实现方法分析
2019/10/02 Python
Python3 使用selenium插件爬取苏宁商家联系电话
2019/12/23 Python
浅谈PyTorch的可重复性问题(如何使实验结果可复现)
2020/02/20 Python
Django项目uwsgi+Nginx保姆级部署教程实现
2020/04/19 Python
使用CSS3的::selection改变选中文本颜色的方法
2015/09/29 HTML / CSS
使用HTML5的Notification API制作web通知的教程
2015/05/08 HTML / CSS
大学生职业生涯规划范文
2013/12/31 职场文书
蔬菜基地的创业计划书
2014/01/06 职场文书
高三地理教学反思
2014/01/11 职场文书
农村党支部先进事迹
2014/01/14 职场文书
幼儿园保教管理制度
2014/02/03 职场文书
合伙开公司协议书范本
2014/10/28 职场文书
电工实训报告总结
2014/11/05 职场文书
2014年售票员工作总结
2014/11/19 职场文书
五星级酒店前台接待岗位职责
2015/04/02 职场文书