先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
该方法实质上是一种分组插入方法。[1]
比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比[1]较就可能消除多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。
一般的初次取序列的一半为增量,以后每次减半,直到增量为1。
给定实例的shell排序的排序过程
假设待排序文件有10个记录,其关键字分别是:
49,38,65,97,76,13,27,49,55,04。
增量序列的取值依次为:
5,2,1
- using System;
- public class ShellSorter
- {
- public void Sort(int[] list)
- {
- int inc;
- for (inc = 1; inc <= list.Length / 9; inc = 3 * inc + 1) ;
- for (; inc > 0; inc /= 3)
- {
- for (int i = inc + 1; i <= list.Length; i += inc)
- {
- int t = list[i - 1];
- int j = i;
- while ((j > inc) && (list[j - inc - 1] > t))
- {
- list[j - 1] = list[j - inc - 1];
- j -= inc;
- }
- list[j - 1] = t;
- }
- }
- }
- }
- public class MainClass
- {
- public static void Main()
- {
- int[] iArrary = new int[] { 1, 5, 3, 6, 10, 55, 9, 2, 87, 12, 34, 75, 33, 47 };
- ShellSorter sh = new ShellSorter();
- sh.Sort(iArrary);
- for (int m = 0; m <= 13; m++)
- Console.WriteLine("{0}", iArrary[m]);
- Console.ReadKey();
- }
- }
- for (int i = k; i < len; i++)
- {
- if (arry[i - k] > arry[i])
- {
- int temp;
- temp = arry[i - k];
- arry[i - k] = arry[i];
- arry[i] = temp;
- }
- }
- }
- foreach (int i in arry)
- {
- Console.WriteLine(i);
- }
- Console.ReadLine();
- program ShellSorter;
- type arr=array[1..n] of integer;
- var a:arr;
- i,n,j,t,d:integer;
- bool:boolean;
- begin
- readln(n);
- for i:=1 to n do read(a[i]);writeln;
- d:=n;
- while d>1 do begin d:=d div 2;
- for j:=d+1 to n do begin t:=a[j];
- i:=j-d;
- while (i>0) and (a[i]>t) do
- begin
- a[i+d]:=a[i];
- i:=i-d;
- end;
- a[i+d]:=t;
- end;
- end;
- for i:=1 to n do write(a[i]:6);
- writeln;
- end.
复制代码 [摘自百度百科]
|