希尔排序
先将整个待排序的序列分割成若干个子序列分别进行直接插入排序,当整个序列的元素“基本有序”时,再对全体进行一次直接插入排序。
需要注意的是,子序列的构成不是简单的“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列,如第一趟增量为5,第二趟增量可以为3等等。
这个增量习惯上用字母h来表示这个增量, 常用的h序列由Knuth提出,该序列从1开始,通过如下公式产生:h = 3 * h +1。
例如下述过程:
希尔排序稳定性
希尔排序是不稳定的算法,它满足稳定算法的定义。对于相同的两个数,可能由于分在不同的组中而导致它们的顺序发生变化。
希尔排序时间复杂度
希尔排序的时间复杂度与增量(即步长gap)的选取有关。如,当增量为1时,希尔排序退化为直接插入排序,此时的时间复杂度为0(N),而Hibbard增量的希尔排序的时间复杂度为0(N^3/2)。
Java实现
package acm; /*希尔排序 * 2017.11.22 * 希尔排序算法减小数据项的间隔再进行排序,依次进行下去,进行这些排序时的数据项 * 之间的间隔被称为增量,习惯上用字母h来表示这个增量。 * 常用的h序列由Knuth提出,该序列从1开始,通过如下公式产生:h = 3 * h +1 */ public class ShellSort { static void shellSort(int[] ary){ int h = 1; //计算h可取的最大值 while(h <= ary.length/3){ h = 3*h+1; } while(h>0){ for(int i=h;i<ary.length;i+=h){ if(ary[i]<ary[i-h]){ int temp = ary[i]; int j = i-h; while(j>=0 && ary[j]>temp){ ary[j+h] = ary[j]; j-=h; } ary[j+h] = temp; for(int ele:ary){ System.out.print(ele+","); } System.out.println("");//换行 } } h = (h-1)/3; } } public static void main(String[] args){ int[] ary = new int[]{49,38,65,97,76,13,27,49,55,4}; shellSort(ary); } }
本文出自 “卫莨” 博客,请务必保留此出处http://acevi.blog.51cto.com/13261784/1983982
原文地址:http://acevi.blog.51cto.com/13261784/1983982