1 static void Main(string[] args) 2 { 3 int n; 4 n = int.Parse(Console.ReadLine()); 5 int[] SeqList = new int[n]; 6 for (int i = 0; i < n; i++) 7 { 8 SeqList[i] = Convert.ToInt32(Console.ReadLine()); 9 } 10 HillInsert(SeqList); 11 foreach (var str in SeqList) 12 { 13 Console.Write(str + " "); 14 } 15 Console.ReadKey(); 16 17 } 18 static void HillInsert(int[] s) 19 { 20 for (int gap = s.Length / 2; gap > 0; gap /= 2) //gap步长的分组次数即为循环次数 21 { 22 for (int i = gap; i < s.Length; i++) //从i=gap开始,依次往后循环, 23 { 24 for (int j = i - gap; j >= 0 && s[j] > s[j + gap]; j -= gap)//比较i-gap与i的大小,j-=gap的目的在于当后续的序列可以分为多组时,需要将这些组依次比较
25 { 26 int temp = s[j]; 27 s[j] = s[j + gap]; 28 s[j + gap] = temp; 29 } 30 } 31 } 32 }
假设一组数据为 49 38 65 97 76 13 27 49* 55 4
步长gap按n/2设定,则第一步可分为{49,13},{38,27},{65,49*},{97,55},{76,4},gap=5
第二个循环则是令i=5,即13这个数,在接下来的循环里,用13与49比较,若小于则交换,然后便是27与38比较,以此类推
此时第一趟排序已经完成: 13,27,49*, 55, 4, 49, 38, 65, 97, 76
第二趟排序gap=2,分组为:{13,49*,4,38,97},{27,55,49,65,76},因为每一组里的个数都超过两个,所以必然会进行多次比较,因此在第三层循环里的j-=gap的作用便是依次比较
第二层循环i=2,即49*这个数,与13比较,大于,跳出,i++,i=3,即55这个数,与27比较,大于,跳出,i++,i=4,即4这个数,与49*比较,小于,交换,j=j-gap,此时前面还有一个13,j=0(即存在两个步长),再用4与13比较,小于,交换,j=j-gap<0,跳出。
以此类推。