希尔排序 是一种插入排序法,它出自D.L.Shell,因此而得名。Shell排序又称作缩小增量排序。
基本思想:
不断把待排序的对象分成若干个小组,对同一小组内的对象采用直接插入法排序,当完成了所有对象都分在一个组内的排序后,排序过程结束。每次比较指定间距 的两个数据项,若左边的值小于右边的值,则交换它们的位置。间距d按给定公式减少: di+1=(di +1)/2 ,直到d等于1为止。D可以选取{9,5,3,2,1}。
using System; using System.Collections.Generic; namespace Com.Colobu.Algorithm.Insertion { /// <summary> /// <b>Shell sort</b> is a sorting algorithm that is a generalization of insertion sort, /// with two observations: /// insertion sort is efficient if the input is "almost sorted" /// insertion sort is typically inefficient because it moves values just one position at a time. /// /// 对有n个元素的可比较资料,先取一个小于n的整数d1作为第一个增量, /// 把文件的全部记录分成d1个组。 /// 所有距离为d1的倍数的记录放在同一个组中。 /// 先在各组内进行直接插入排序;然后,取第二个增量d2<d1 /// 重复上述的分组和排序,直至所取的增量dt=1(dt<dt-1<…<d2<d1), /// 即所有记录放在同一组中进行直接插入排序为止。 /// 该方法实质上是一种分组插入方法。 /// /// 平均时间复杂度:O(nlogn) /// Stability:No /// </summary> public class ShellSortAlgorithm { public static void ShellSort<T>(IList<T> szArray) where T : IComparable { int i, j, k, gap; T temp; //gap sequence:a(n) = floor(fibonacci(n+1)^(1+sqrt(5))) //the Fibonacci numbers (leaving out one of the starting 1's) to the power of twice the golden ratio int[] gaps = { 1,5,13,43,113,297,815,1989,4711,11969,27901,84801, 213331,543749,1355339,3501671,8810089,21521774, 58548857,157840433,410151271,1131376761,2147483647 }; int n = szArray.Count; //从素数序列中得到一个满足条件的最大的素数 for (k = 0; gaps[k] < n; k++) ; while (--k >= 0) { gap = gaps[k]; //取增量 for (i = gap; i < n; i++) //按照此增量分组 { temp = szArray[i]; j = i; while (j >= gap && szArray[j - gap].CompareTo(temp) > 0) //将此组插入排序 { szArray[j] = szArray[j - gap]; j = j - gap; } szArray[j] = temp; } } } } }