标签:很多 没有 blog sort 循环 数组 不同 多少 操作
希尔排序,插入排序的升级排版
先回顾插入排序
1从集合第二个元素开始(外循环开始)
2取出该元素 标记为C
3从该元素开始,向前遍历,如果元素大于C,则该元素向后移动一位(内循环)
4直到找到一个小于或者等于C元素(或者到达集合头部),将C放在这个元素的下一位(或者集合头部)
重复1(注意选取下一个元素)(外循环第一趟完成,进入第二趟循环)
可以发现问题:
数组: 5,1,2,3,4,0,6,7,8,9
按照从小到大排序会使得多个元素交换位子,这是比较消耗性能的,这里使用希尔排序会高效很多
希尔排序的思路是选取一个步长,将数组进行分组,每一组在进行插入排序,然后减少步长,在进行插入排序,直到步长减少到1
举例说明:
数组 4,5,6,1,2,3
1.选取步长3
2. 对数组进行一个分组处理,如下(实际不处理),分组方式:从0位元素与0+n步长 元素 都为第一组,
第1位元素与1+n步长 元素 都为 第二组 (以此类推,有多少组取决于步长)
4 5 6 1 2 3
a b c a b c
3可以看出分了3组(a,b,c3个组),对每一组分别进行插入排序
4减少步长重复 2,3操作,直到步长为1
代码:
1 /// <summary> 2 /// 希尔排序 3 /// </summary> 4 public static void ShellSort(int[] array) 5 { 6 //最外面的循环,控制步长逐步减少至1 7 for (int p = array.Length/2; p >0 ; p/=2) 8 { 9 //循环所有组 10 for (int g = 0; g < p; g++) 11 { 12 //这里面就是插入排序代码(稍微与之前的插入排序有点不同) 13 for (int i = g + p; i < array.Length; i = i + p) 14 { 15 int c = array[i]; 16 for (int j = i - p; j >= -p; j = j - p) 17 { 18 if (j < 0) 19 { 20 array[j + p] = c; 21 break; 22 } 23 //比当前元素大的后移一位 24 else if (array[j] > c) 25 { 26 array[j + p] = array[j]; 27 } 28 else 29 { 30 if (j + p != i) 31 { 32 //j+1 !+ i说明元素位子发生改变,否则不需要赋值操作 33 array[j + p] = c; 34 } 35 break; 36 } 37 } 38 } 39 } 40 41 } 42 43 }
总结
希尔排序最主要就是选取一个步长进行分组,步长选择好像有个什么最优处理,具体可以百度
希尔排序难点在于分组,然后对每一组进行排序,这个我一开始就没搞懂,怎么分组,然后又怎么分别插入排序
分组是在逻辑上分组,比如上面的a组,就是元素 数组 [0] 与元素 数组[3] 2个元素进行插入排序,实际上是没有对数组做任何处理的
希尔排序这样做的作用就是将数组 局部有序,再整体插入排序(如数组 5,1,2,3,4,0,6,7,8,9 操作:选取步长5,在第一次插入排序是时5与0会分到一组,交换后整体就有序了,这里交换了一次就完成排序,如果直接进行整体插入排序就会出现多次交换)
排序算法到此先告一段落,接下来搞数据结构了
标签:很多 没有 blog sort 循环 数组 不同 多少 操作
原文地址:http://www.cnblogs.com/bigA/p/7424923.html