1. 程式人生 > >算法七之希爾排序

算法七之希爾排序

sys 關鍵詞 alt spa 最終 https 最優 src middle

一、希爾排序

(1)簡介

  希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進版本。希爾排序是非穩定排序算法。該方法因DL.Shell於1959年提出而得名。   希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。 (2)基本思想   先取一個小於n的整數d1作為第一個增量,把文件的全部記錄分組。所有距離為d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然後,取第二個增量d2<d1重復上述的分組和排序,直至所取的增量 技術分享
=1( 技術分享 < 技術分享 …<d2<d1),即所有記錄放在同一組中進行直接插入排序為止。   該方法實質上是一種分組插入方法比較相隔較遠距離(稱為增量)的數,使得數移動時能跨過多個元素,則進行一次比較就可能消除多個元素交換。算法先將要排序的一組數按某個增量d分成若幹組,每組中記錄的下標相差d.對每組中全部元素進行排序,然後再用一個較小的增量對它進行,在每組中再進行排序。當增量減到1時,整個要排序的數被分成一組,排序完成。   一般的初次取序列n的一半為增量,以後每次減半(盡量不要是前一個增量的倍數,否則效率低下),直到增量為1。

二、算法實現

package cn.edu.scau.mk;

import java.util.Arrays; /** * * @author MK */ public class ShellSort { /** * 每次增量進行的插入排序 * @param data 序列 * @param dk 增量 */ private static void shellInsert(int[] data,int dk){ int j; int temp;//臨時空間 //遍歷dk組序列 for (int i = dk; i < data.length; i++) {
//與前dk個元素的比較 if(data[i-dk]>data[i]){ temp=data[i]; //臨時保存 //直到比當前i所在元素小才停止 for (j = i-dk; j >=0&&data[j]>temp; j-=dk) { data[j+dk]=data[j]; } data[j+dk]=temp; //回填數據 } } } /** * 希爾排序 * @param data 序列 */ public static void shellSort(int[] data) { //增量 int dk=data.length/2; //增量最終減到為1 while (dk>=1) { shellInsert(data, dk); dk/=2; } } public static void main(String[] args) { int[] data={2,3,1,3}; shellSort(data); System.out.println(Arrays.toString(data)); } }

三、算法復雜度

  最好時間O(n);最壞時間O(ns),(1<s<2);平均時間O(nlogn);不穩定;Hibbard增量dk=2t-k+1-1,(1<=k<=t<?log2(n+1)?),希爾排序的時間復雜度為O( 技術分享 ),希爾排序時間復雜度的下界是nlog2n,沒有快速排序算法快 O(nlogn),因此中等大小規模表現良好,對規模非常大的數據排序不是最優選擇。

算法七之希爾排序