PHP排序算法之希尔排序(Shell Sort)实例分析


Posted in PHP onApril 20, 2018

本文实例讲述了PHP排序算法之希尔排序(Shell Sort)。分享给大家供大家参考,具体如下:

基本思想:

希尔排序是指记录按下标的一定增量分组,对每一组使用 直接插入排序 ,随着增量逐渐减少,每组包含的关键字越来越多,当增量减少至 1 时,整个序列恰好被分成一组,算法便终止。

操作步骤:

先取一个小于 n(序列记录个数) 的整数 d1 作为第一个增量,把文件的全部记录分组。所有距离为 d1 的倍数的记录放在同一个组中。先在各组内进行 直接插入排序;然后,取第二个增量 d2 < d1 重复上述的分组和排序,直至所取的增量 dt=1( dt < d(t-1) …< d2 < d1),即所有记录放在同一组中进行 直接插入排序 为止.

该方法实质上是一种分组插入方法

比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比[2] 较就可能消除多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。

一般的初次取序列的一半为增量,以后每次减半,直到增量为1。

关于增量的取法,据说迄今为止还没有找到一种最好的增量序列,不过有一个强烈的要求是 最后一个增量值必须等于 1 才行。

给定实例的shell排序的排序过程

假设待排序文件有10个记录,其关键字分别是:

49,38,65,97,76,13,27,49,55,04。

增量序列的取值依次为:

5,3,1

PHP排序算法之希尔排序(Shell Sort)实例分析

算法实现:

<?php
//希尔排序(对直接插入排序的改进)
function ShellSort(array &$arr)
{
  $count = count($arr);
  $inc = $count;  //增量
  do {
    //计算增量
    //$inc = floor($inc / 3) + 1;
    $inc = ceil($inc / 2);
    for ($i = $inc; $i < $count; $i++) {
      $temp = $arr[$i];  //设置哨兵
      //需将$temp插入有序增量子表
      for ($j = $i - $inc; $j >= 0 && $arr[$j + $inc] < $arr[$j]; $j -= $inc) {
        $arr[$j + $inc] = $arr[$j]; //记录后移
      }
      //插入
      $arr[$j + $inc] = $temp;
    }
    //增量为1时停止循环
  } while ($inc > 1);
}
//$arr = array(9,1,5,8,3,7,4,6,2);
$arr = array(49,38,65,97,76,13,27,49,55,04);
ShellSort($arr);
var_dump($arr);

运行结果:

array(10) {
 [0]=>
 int(4)
 [1]=>
 int(13)
 [2]=>
 int(27)
 [3]=>
 int(38)
 [4]=>
 int(49)
 [5]=>
 int(49)
 [6]=>
 int(55)
 [7]=>
 int(65)
 [8]=>
 int(76)
 [9]=>
 int(97)
}

复杂度分析:

通过以上代码的分析,相信大家已经有些明白,希尔排序的关键并不是随便分组后各自排序,而是将相隔某个“增量”的记录组成一个子序列,实现跳跃式的移动,使得排序的效率提高。

最坏的情况下时间复杂度是 O(n^2)

希尔排序是不稳定排序。

本文参考自《大话数据结构》,在此仅作记录,方便以后查阅,大神勿喷!

PHP 相关文章推荐
phpmyadmin安装时提示:Warning: require_once(./libraries/common.inc.php)错误解决办法
Aug 18 PHP
PHP实现图片压缩的两则实例
Jul 19 PHP
php实现字符串首字母转换成大写的方法
Mar 17 PHP
百度地图API使用方法详解
Aug 25 PHP
Yii2中OAuth扩展及QQ互联登录实现方法
May 16 PHP
php解析xml 的四种简单方法(附实例)
Jul 11 PHP
PHP读取文件的常见几种方法
Nov 03 PHP
PHP合并数组的2种方法小结
Nov 24 PHP
php使用curl代理实现抓取数据的方法
Feb 03 PHP
PHP基于简单递归函数求一个数阶乘的方法示例
Apr 26 PHP
laravel配置Redis多个库的实现方法
Apr 10 PHP
Laravel Eloquent ORM 实现查询表中指定的字段
Oct 17 PHP
PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析
Apr 20 #PHP
PHP排序算法之简单选择排序(Simple Selection Sort)实例分析
Apr 20 #PHP
PHP排序算法之冒泡排序(Bubble Sort)实现方法详解
Apr 20 #PHP
PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解
Apr 20 #PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
Apr 20 #PHP
Laravel 加载第三方类库的方法
Apr 20 #PHP
PHP迭代器和迭代的实现与使用方法分析
Apr 19 #PHP
You might like
德劲1103的维修打理经验
2021/03/02 无线电
用PHP实现Ftp用户的在线管理的代码
2007/03/06 PHP
php 3行代码的分页算法(求起始页和结束页)
2009/10/21 PHP
PHP学习笔记(三):数据类型转换与常量介绍
2015/04/17 PHP
PHP的命令行命令使用指南
2015/08/18 PHP
推荐dojo学习笔记
2007/03/24 Javascript
IE 条件注释详解总结(附实例代码)
2009/08/29 Javascript
JavaScript ECMA-262-3 深入解析.第三章.this
2011/09/28 Javascript
node.js中的fs.writeFile方法使用说明
2014/12/14 Javascript
javascript获得当前的信息的一些常用命令
2015/02/25 Javascript
原生JavaScript制作微博发布面板效果
2016/03/11 Javascript
AngularJS在IE下取数据总是缓存问题的解决方法
2016/08/05 Javascript
JS二叉树的简单实现方法示例
2017/04/05 Javascript
Bootstrap 模态框多次显示后台提交多次BUG的解决方法
2017/12/26 Javascript
详解Node使用Puppeteer完成一次复杂的爬虫
2018/04/18 Javascript
详解ES6 Fetch API HTTP请求实用指南
2018/11/14 Javascript
JS实现提示框跟随鼠标移动
2019/08/27 Javascript
vue element-ui中table合计指定列求和实例
2020/11/02 Javascript
[03:09]2014DOTA2国际邀请赛 Mushi前队友送上祝福
2014/07/12 DOTA
简化Python的Django框架代码的一些示例
2015/04/20 Python
python类和继承用法实例
2015/07/07 Python
Python3实现简单可学习的手写体识别(实例讲解)
2017/10/21 Python
Python FTP两个文件夹间的同步实例代码
2018/05/25 Python
pycharm: 恢复(reset) 误删文件的方法
2018/10/22 Python
pycharm执行python时,填写参数的方法
2018/10/29 Python
Python实现常见的回文字符串算法
2018/11/14 Python
python多线程调用exit无法退出的解决方法
2019/02/18 Python
django自带调试服务器的使用详解
2019/08/29 Python
tensorflow中tf.reduce_mean函数的使用
2020/04/19 Python
Python页面加载的等待方式总结
2021/02/28 Python
世界顶级足球门票网站:Live Football Tickets
2017/10/14 全球购物
微软台湾官方网站:Microsoft台湾
2018/08/15 全球购物
行政经理岗位职责
2013/11/09 职场文书
2014年员工工作总结范文
2014/11/18 职场文书
董事长致辞
2015/07/29 职场文书
Golang实现可重入锁的示例代码
2022/05/25 Golang