PHP排序算法之希爾排序(Shell Sort)實(shí)例分析
本文實(shí)例講述了PHP排序算法之希爾排序(Shell Sort)。分享給大家供大家參考,具體如下:
基本思想:
希爾排序是指記錄按下標(biāo)的一定增量分組,對(duì)每一組使用 直接插入排序 ,隨著增量逐漸減少,每組包含的關(guān)鍵字越來(lái)越多,當(dāng)增量減少至 1 時(shí),整個(gè)序列恰好被分成一組,算法便終止。
操作步驟:
先取一個(gè)小于 n(序列記錄個(gè)數(shù)) 的整數(shù) d1 作為第一個(gè)增量,把文件的全部記錄分組。所有距離為 d1 的倍數(shù)的記錄放在同一個(gè)組中。先在各組內(nèi)進(jìn)行 直接插入排序;然后,取第二個(gè)增量 d2 < d1 重復(fù)上述的分組和排序,直至所取的增量 dt=1( dt < d(t-1) …< d2 < d1),即所有記錄放在同一組中進(jìn)行 直接插入排序 為止.
該方法實(shí)質(zhì)上是一種分組插入方法
比較相隔較遠(yuǎn)距離(稱為增量)的數(shù),使得數(shù)移動(dòng)時(shí)能跨過(guò)多個(gè)元素,則進(jìn)行一次比[2] 較就可能消除多個(gè)元素交換。D.L.shell于1959年在以他名字命名的排序算法中實(shí)現(xiàn)了這一思想。算法先將要排序的一組數(shù)按某個(gè)增量d分成若干組,每組中記錄的下標(biāo)相差d.對(duì)每組中全部元素進(jìn)行排序,然后再用一個(gè)較小的增量對(duì)它進(jìn)行,在每組中再進(jìn)行排序。當(dāng)增量減到1時(shí),整個(gè)要排序的數(shù)被分成一組,排序完成。
一般的初次取序列的一半為增量,以后每次減半,直到增量為1。
關(guān)于增量的取法,據(jù)說(shuō)迄今為止還沒有找到一種最好的增量序列,不過(guò)有一個(gè)強(qiáng)烈的要求是 最后一個(gè)增量值必須等于 1 才行。
給定實(shí)例的shell排序的排序過(guò)程
假設(shè)待排序文件有10個(gè)記錄,其關(guān)鍵字分別是:
49,38,65,97,76,13,27,49,55,04。
增量序列的取值依次為:
5,3,1
算法實(shí)現(xiàn):
<?php //希爾排序(對(duì)直接插入排序的改進(jìn)) function ShellSort(array &$arr) { $count = count($arr); $inc = $count; //增量 do { //計(jì)算增量 //$inc = floor($inc / 3) + 1; $inc = ceil($inc / 2); for ($i = $inc; $i < $count; $i++) { $temp = $arr[$i]; //設(shè)置哨兵 //需將$temp插入有序增量子表 for ($j = $i - $inc; $j >= 0 && $arr[$j + $inc] < $arr[$j]; $j -= $inc) { $arr[$j + $inc] = $arr[$j]; //記錄后移 } //插入 $arr[$j + $inc] = $temp; } //增量為1時(shí)停止循環(huán) } 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);
運(yùn)行結(jié)果:
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) }
復(fù)雜度分析:
通過(guò)以上代碼的分析,相信大家已經(jīng)有些明白,希爾排序的關(guān)鍵并不是隨便分組后各自排序,而是將相隔某個(gè)“增量”的記錄組成一個(gè)子序列,實(shí)現(xiàn)跳躍式的移動(dòng),使得排序的效率提高。
最壞的情況下時(shí)間復(fù)雜度是 O(n^2)。
希爾排序是不穩(wěn)定排序。
本文參考自《大話數(shù)據(jù)結(jié)構(gòu)》,在此僅作記錄,方便以后查閱,大神勿噴!
PS:這里再為大家推薦一款關(guān)于排序的演示工具供大家參考:
在線動(dòng)畫演示插入/選擇/冒泡/歸并/希爾/快速排序算法過(guò)程工具:
http://tools.jb51.net/aideddesign/paixu_ys
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php排序算法總結(jié)》、《PHP數(shù)據(jù)結(jié)構(gòu)與算法教程》、《php程序設(shè)計(jì)算法總結(jié)》、《php字符串(string)用法總結(jié)》、《PHP數(shù)組(Array)操作技巧大全》、《PHP常用遍歷算法與技巧總結(jié)》及《PHP數(shù)學(xué)運(yùn)算技巧總結(jié)》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
相關(guān)文章
用緩存實(shí)現(xiàn)靜態(tài)頁(yè)面的測(cè)試
用緩存實(shí)現(xiàn)靜態(tài)頁(yè)面的測(cè)試...2006-12-12PHP封裝的PDO數(shù)據(jù)庫(kù)操作類實(shí)例
這篇文章主要介紹了PHP封裝的PDO數(shù)據(jù)庫(kù)操作類,結(jié)合具體實(shí)例形式分析了php基于PDO針對(duì)數(shù)據(jù)庫(kù)的增刪改查、事務(wù)、批量添加等相關(guān)操作技巧,需要的朋友可以參考下2017-06-06PHP性能分析工具xhprof的安裝使用與注意事項(xiàng)
xhprof 是一款Facebook工程師開發(fā)和維護(hù)的一款PHP性能分析、調(diào)試工具,相較于xdebug要更輕量,更節(jié)省資源,強(qiáng)烈推薦大家使用。下面這篇文章主要給大家介紹了關(guān)于PHP性能分析工具xhprof的安裝與使用方法的相關(guān)資料,需要的朋友可以參考下。2017-12-12PHP版 漢字轉(zhuǎn)碼的實(shí)現(xiàn)詳解
本篇文章是對(duì)用php實(shí)現(xiàn)漢字轉(zhuǎn)碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06php約瑟夫問(wèn)題解決關(guān)于處死犯人的算法
這篇文章主要介紹了php約瑟夫問(wèn)題解決關(guān)于處死犯人的算法,實(shí)例分析了php關(guān)于約瑟夫問(wèn)題的實(shí)現(xiàn)與應(yīng)用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03PHP觀察者模式原理與簡(jiǎn)單實(shí)現(xiàn)方法示例
這篇文章主要介紹了PHP觀察者模式原理與簡(jiǎn)單實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了php觀察者模式的概念、原理、實(shí)現(xiàn)方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-08-08深入理解用mysql_fetch_row()以數(shù)組的形式返回查詢結(jié)果
本篇文章是對(duì)使用mysql_fetch_row()以數(shù)組的形式返回查詢結(jié)果進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06Php獲取金書網(wǎng)的書名的實(shí)現(xiàn)代碼
php獲取金書網(wǎng)的書名的實(shí)現(xiàn)代碼。2010-06-06php去掉數(shù)組的key重組數(shù)組的四種方法
在PHP開發(fā)中數(shù)組是常用的數(shù)據(jù)結(jié)構(gòu)之一,在處理數(shù)組時(shí)有時(shí)候需要去掉數(shù)組的key,只取數(shù)組中的值,這篇文章主要給大家介紹了關(guān)于php去掉數(shù)組的key重組數(shù)組的四種方法,需要的朋友可以參考下2023-12-12