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代码
Apr 09 PHP
php 过滤危险html代码
Jun 29 PHP
php 魔术方法使用说明
Oct 20 PHP
PHP中一些可以替代正则表达式函数的字符串操作函数
Nov 17 PHP
Json_encode防止汉字转义成unicode的方法
Feb 25 PHP
PHP创建/删除/复制文件夹、文件
May 03 PHP
php版微信公众平台实现预约提交后发送email的方法
Sep 26 PHP
php中preg_replace正则替换用法分析【一次替换多个值】
Jan 17 PHP
Yii CDBCriteria常用方法实例小结
Jan 19 PHP
PHP中trait使用方法详细介绍
May 21 PHP
laravel 数据验证规则详解
Oct 23 PHP
Thinkphp 框架扩展之标签库驱动原理与用法分析
Apr 23 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
在PWS上安装PHP4.0正式版
2006/10/09 PHP
php简单对象与数组的转换函数代码(php多层数组和对象的转换)
2011/05/18 PHP
php学习笔记 面向对象的构造与析构方法
2011/06/13 PHP
深入php内核之php in array
2015/11/10 PHP
PHP保存session到memcache服务器的方法
2016/01/19 PHP
PHP信号量基本用法实例详解
2016/02/12 PHP
PHP中函数gzuncompress无法使用的解决方法
2017/03/02 PHP
[原创]php使用strpos判断字符串中数字类型子字符串出错的解决方法
2017/04/01 PHP
php+ajax实现异步上传文件或图片功能
2017/07/18 PHP
Laravel中10个有用的用法小结
2019/05/06 PHP
php面向对象重点知识分享
2019/09/27 PHP
打豆豆小游戏 用javascript编写的[打豆豆]小游戏
2013/01/08 Javascript
JS案例分享之金额小写转大写
2014/05/15 Javascript
JavaScript访问CSS属性的几种方式介绍
2014/07/21 Javascript
检测一个函数是否是JavaScript原生函数的小技巧
2015/03/13 Javascript
js一维数组、多维数组和对象的混合使用方法
2016/04/03 Javascript
jquery购物车结算功能实现方法
2020/10/29 Javascript
JS检测数组类型的方法小结
2017/03/14 Javascript
Angular 1.x个人使用的经验小结
2017/07/19 Javascript
收集前端面试题之url、href、src
2018/03/22 Javascript
layui-select动态选中值的例子
2019/09/23 Javascript
[01:06] DOTA2英雄背景故事第三期之秩序法则光之守卫
2020/07/07 DOTA
Python pickle模块用法实例分析
2015/05/27 Python
在scrapy中使用phantomJS实现异步爬取的方法
2018/12/17 Python
Python面向对象封装操作案例详解 II
2020/01/02 Python
使用python 的matplotlib 画轨道实例
2020/01/19 Python
基于pycharm 项目和项目文件命名规则的介绍
2021/01/15 Python
Python3+Django get/post请求实现教程详解
2021/02/16 Python
纯CSS3制作的简洁蓝白风格的登录模板(非IE效果更好)
2013/08/11 HTML / CSS
BudgetAir印度:预订航班、酒店和汽车租赁
2019/07/07 全球购物
自我鉴定书范文
2013/10/02 职场文书
优秀生推荐信范文
2013/11/28 职场文书
安全事故检讨书
2014/01/18 职场文书
实习生岗位职责
2014/04/12 职场文书
原生JS实现分页
2022/04/19 Javascript
SQL Server Agent 服务无法启动
2022/04/20 SQL Server