Shell(希尔)排序
希尔排序(Shell Sort)是插入排序的一种,是对直接插入法排序的一种改进。
希尔排序是按照分治法的思想,将原来的元素分成几个组,在组内采用直接插入法进行排序。
时间复杂度:O(n^1.3~2.5) 不稳定
如:6 9 2 7 5 3
按照关键字进行分组:我们选取3 和 1 。
首先按照关键字 3 来分组:【6 7】【9 5】【2 3】
组内按照直接插入法排序:【6 7】【5 9】【2 3】
得到新的序列:6 7 5 9 2 3
按照关键字 1 来分组(实际上也就是 1 组):【6 7 5 9 2 3】
组内按照直接插入法排序得到新的序列:2 3 5 6 7 9
ok
希尔排序法的关键在于关键字的选择,关键字的选择有如下规则:
- 关键字必须为素数。
- 最后一个关键字必须为 1 。
用这个简单的例子来帮助大家理解一下。下面我们换一个例子来深入的理解一下它,顺便用代码来实现希尔排序。
23 4 34 54 65 76 22 3 56 13 35 28 32 43 5
我们按照关键字 5 3 1 来进行排序 。下面相同颜色的为 1 组。
按关键字 5 分组:【23 76 35】【4 22 28】【34 3 32】【54 56 43】【65 13 5】
排序:【23 35 76】【4 22 28】【3 32 34】【43 54 56】【5 13 65】
按照关键字 3 分组:【23 43 22 13 34】【4 5 32 76 56】【3 35 54 28 65】
排序:【13 22 23 34 43】【4 5 32 56 76】【3 28 35 54 65】
按照关键字 1 分组:【13 4 3 22 5 28 23 32 35 34 56 54 43 76 65】
排序:【3 4 5 13 22 23 28 32 34 35 43 54 56 65 76】
下面我们用 java 来实现以下这个算法。
这个是组内排序的代码。算法的思想就是直接插入法排序。
public static void shell(int[] array,int gap){ int tmp = 0; for(int i = gap;i < array.length;i += gap){ tmp = array[i]; int j = 0; for(j = i-gap;j >= 0;j -= gap){ if(array[j] > tmp){ //??????? array[j+gap] = array[j]; }else{ break; } } array[j+gap] = tmp; } }
希尔排序。
像我们之前推导的一样,分别按照关键字5 3 1 进行排序。
public static void shellSort(int[] array){ int[] d = {5,3,1}; for(int i = 0;i < d.length;i++){ shell(array,d[i]); } }