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 相关文章推荐
PHP调用三种数据库的方法(1)
Oct 09 PHP
php快速url重写更新版[需php 5.30以上]
Apr 25 PHP
解析PHP计算页面执行时间的实现代码
Jun 18 PHP
div li的多行多列 无刷新分页示例代码
Oct 16 PHP
php实现把url转换迅雷thunder资源下载地址的方法
Nov 07 PHP
php之readdir函数用法实例
Nov 13 PHP
php截取中文字符串函数实例
Feb 23 PHP
PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
Nov 16 PHP
PHP基于单例模式实现的mysql类
Jan 09 PHP
详解PHP的Laravel框架中Eloquent对象关系映射使用
Feb 26 PHP
YII2框架中actions的作用与使用方法示例
Mar 13 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
Jun 24 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
PHP创建/删除/复制文件夹、文件
2016/05/03 PHP
JS 非图片动态loading效果实现代码
2010/04/09 Javascript
JavaScript中一个奇葩的IE浏览器判断方法
2014/04/16 Javascript
ECMAScript5(ES5)中bind方法使用小结
2015/05/07 Javascript
javascript框架设计之浏览器的嗅探和特征侦测
2015/06/23 Javascript
通过BootStrap-select插件 js jQuery控制select属性变化
2017/01/03 Javascript
Angular中自定义Debounce Click指令防止重复点击
2017/07/26 Javascript
手写简单的jQuery雪花飘落效果实例
2018/04/22 jQuery
Redux实现组合计数器的示例代码
2018/07/04 Javascript
解决angularjs前后端分离调用接口传递中文时中文乱码的问题
2018/08/13 Javascript
react实现换肤功能的示例代码
2018/08/14 Javascript
浅谈vuex actions和mutation的异曲同工
2018/12/13 Javascript
layui多iframe页面控制定时器运行的方法
2019/09/05 Javascript
ES6 Symbol在对象中的作用实例分析
2020/06/06 Javascript
js实现简单的倒计时
2021/01/28 Javascript
跟老齐学Python之不要红头文件(1)
2014/09/28 Python
Python导入txt数据到mysql的方法
2015/04/08 Python
利用Python爬取可用的代理IP
2016/08/18 Python
Python 基础知识之字符串处理
2017/01/06 Python
python 全局变量的import机制介绍
2017/09/07 Python
python多进程实现进程间通信实例
2017/11/24 Python
TensorFlow实现Logistic回归
2018/09/07 Python
Python读取YUV文件,并显示的方法
2018/12/04 Python
详解python配置虚拟环境
2019/04/08 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
2019/07/19 Python
一篇文章弄懂Python中的可迭代对象、迭代器和生成器
2019/08/12 Python
pycharm实现在子类中添加一个父类没有的属性
2020/03/12 Python
jupyter notebook更换皮肤主题的实现
2021/01/07 Python
css3动画效果小结(推荐)
2016/07/25 HTML / CSS
如何查询Oracle数据库中已经创建的索引
2013/10/11 面试题
森马旗舰店双十一营销方案
2014/09/29 职场文书
领导班子三严三实心得体会
2014/10/13 职场文书
五星级酒店前台接待岗位职责
2015/04/02 职场文书
教师个人教学反思
2016/02/23 职场文书
vue3中的组件间通信
2021/03/31 Vue.js
Python如何导出导入所有依赖包详解
2021/06/08 Python