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 相关文章推荐
单一index.php实现PHP任意层级文件夹遍历(Zjmainstay原创)
Jul 31 PHP
使用php检测用户当前使用的浏览器是否为IE浏览器
Dec 03 PHP
php中限制ip段访问、禁止ip提交表单的代码分享
Aug 22 PHP
php函数serialize()与unserialize()用法实例
Nov 06 PHP
PHP跨平台获取服务器IP地址自定义函数分享
Dec 29 PHP
PHP实现生成唯一会员卡号
Aug 24 PHP
PHP截取IE浏览器并缩小原图的方法
Mar 04 PHP
PHP解决中文乱码
Apr 28 PHP
PHP多进程之pcntl_fork的实例详解
Oct 15 PHP
PHP Trait代码复用类与多继承实现方法详解
Jun 17 PHP
Thinkphp5框架实现获取数据库数据到视图的方法
Aug 14 PHP
php面向对象重点知识分享
Sep 27 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中取得image按钮传递的name值
2006/10/09 PHP
PHP实现转盘抽奖算法分享
2020/04/15 PHP
php+redis实现消息队列功能示例
2019/09/19 PHP
prototype Element学习笔记(篇一)
2008/10/26 Javascript
Extjs学习笔记之八 继承和事件基础
2010/01/08 Javascript
node.js中的fs.readlink方法使用说明
2014/12/17 Javascript
js在指定位置增加节点函数insertBefore()用法实例
2015/01/12 Javascript
jquery图片切换插件
2015/03/16 Javascript
基于JavaScript代码实现pc与手机之间的跳转
2015/12/23 Javascript
使用递归遍历对象获得value值的实现方法
2016/06/14 Javascript
JavaScript递归操作实例浅析
2016/10/31 Javascript
BootStrap实现响应式布局导航栏折叠隐藏效果(在小屏幕、手机屏幕浏览时自动折叠隐藏)
2016/11/30 Javascript
bootstrapValidator bootstrap-select验证不可用的解决办法
2017/01/11 Javascript
一篇文章搞定JavaScript类型转换(面试常见)
2017/01/21 Javascript
javascript实现秒表计时器的制作方法
2017/02/16 Javascript
微信小程序 滚动到某个位置添加class效果实现代码
2017/04/19 Javascript
three.js实现炫酷的全景3D重力感应
2018/12/30 Javascript
基于vue实现一个禅道主页拖拽效果
2019/05/27 Javascript
基于layui的table插件进行复选框联动功能的实现方法
2019/09/19 Javascript
Vue路由守卫及页面登录权限控制的设置方法(两种)
2020/03/31 Javascript
Vue如何实现验证码输入交互
2020/12/07 Vue.js
Vue仿Bibibili首页的问题
2021/01/21 Vue.js
在Django的模型中添加自定义方法的示例
2015/07/21 Python
Bottle框架中的装饰器类和描述符应用详解
2017/10/28 Python
Django框架封装外部函数示例
2019/05/28 Python
Python集中化管理平台Ansible介绍与YAML简介
2019/06/12 Python
Python 将代码转换为可执行文件脱离python环境运行(步骤详解)
2021/01/25 Python
玩具反斗城美国官网:Toys"R"Us
2016/09/17 全球购物
BrandAlley英国:法国折扣奢侈品网上零售商
2017/07/03 全球购物
英国Flybe航空官网:欧洲最大的独立支线廉价航空公司
2019/07/15 全球购物
应届生人事助理求职信
2013/11/09 职场文书
微型企业创业投资计划书
2014/01/10 职场文书
2014端午节活动策划方案
2014/01/27 职场文书
逃出克隆岛观后感
2015/06/09 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书
使用Redis实现分布式锁的方法
2022/06/16 Redis