一、希尔排序简述和基本思想
希尔排序也称递减增量排序算法,是插入排序的一种更高效的改进版本。但是希尔排序是非稳定排序的算法。希尔排序比一般插入排序有以下几点改进:
- 一般插入排序每次只能将数据移动一位,而希尔排序是按照步长移动的(步长=数组长度/2),步长是递减的。
- 希尔排序是通过多次划分子序列,对子序列进行排序,使得整个序列基本有序,再对整个序列的所有元素进行直接插入排序,提高了最后直接插入排序的效率。
希尔排序的基本思想是:先将整个待排序的序列分割成为若干个子序列分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行依次进行直接插入排序。希尔排序是不稳定排序,希尔排序平均时间复杂度为O(n1.3),最差时间复杂度为O(n2),空间复杂度为O(1)。
二、基本步骤
- 将整个序列分成n/2个子序列,即是第k个数跟n/2+k(k<=n/2)个数为一个子序列。
- 将分好的子序列用插入排序的方式将各个子序列排好序。
- 将整个序列分成n/4个子序列,然后分好的子序列按照插入排序排好序。
- 不断执行以上操作,直到子序列数为1,排序完成。
三、案例分析
以序列 1,5,4,30,6,29,5,20为例
第一趟排序:子序列数=n/2=4 四个子序列为{1,6},{5,29},{4,5},{30,20}将这四个序列排序后为{1,5,4,20,6,29,5,30}。
第二趟排序:子序列数=n/4=2 二个子序列为{1,4,6,5},{5,20,29,30}将这二个序列排序后为{1,5,4,20,5,29,6,30}。
第二趟排序:子序列数=n/8=1 一个子序列为{1,4,6,5 ,5,20,29,30}将这一个序列排序后为{1,4,5,5,6,20,29,30}。
四、代码展示
public class JavaSort { public static void main(String[] args) { int a [] =new int []{1,5,4,30,6,29,5,20}; System.out.println("排序前的数组:"+Arrays.toString(a)); shellSort(a); System.out.println("排序后的数组:"+Arrays.toString(a)); } /** * * @param ary要排序的数组 * @return 返回排序好的数组 */ public static int [] shellSort(int [] ary) { int len=ary.length; for (int num= len/2; num>=1; num=num/2) {//num为子序列数,num也表示子序列元素在原来序列中相差的位置 //找到子序列,子序列用插入排序进行排序 for (int i = num; i < len; i++) { int j=i-num;//子序列元素要插入的位置 int temp=ary[i];//子序列要插入的元素值暂存 while(j>0&&temp<ary[j]) {//将要插入元素子序列元素比较找到要插入元素的位置 ary[j+num]=ary[j]; j=j-num; } ary[j+num]=temp;//插入要插入的子序列元素 } } return ary; } }
运行结果: