从刚开始本科学习数据结构的时候,对希尔排序就一直稀里糊涂的,弄不清到底怎么回事,重温知识,对此才稍加了解,希尔排序就是插入排序,不过它对插入排序进行了一些优化,我们之道,插入排序的性能与初始序列的排序状况有关,假设需要的排序效果是从小到达,如果给定的序列原本就是有序的,那么排序的时候只需遍历一遍数组就可以了;但是,如果给定的序列原本是逆序的,必须 5 4 3 2 1,那么对数组的中的数据(注意,这里是数据,而非数组)扫描的次数大约是(5+4+3+2+1)次,也就是说如果给定n个数据,排序的时间复杂度是O(n^2),所以,插入排序对于具有“良好有序性”的序列(也就是说序列不是逆序的)来说,其排序效果还是不错的;但是对于纯逆序的序列来说,排序效果就不是那么好了,这时候,希尔排序的优化效果就体现出来了,它的思想是这样的:先对局部序列进行数次插入排序,这样可以使整体序列趋于有序,最后对整体序列进行插入排序,就可以得到有序的序列。下面用一张图进行说明:
图中,相同颜色的数据组成一个子序列,子序列进行插入排序。这里增量step采用减半的形式求解,也就是对于长度为10的序列,step的取值为5、2、1,从图中可以看出,当step=1的时候,是对整个序列进行插入排序,这时候整个序列已经“整体有序”,所以利用插入排序对数据的访问此次不回很多。具体代码如下:
public class Test{ public static void main(String[] args)throws InterruptedException{ int[] array={32,56,34,23,43,45,23,54,56,31,322}; printArray(array); int temp=0,x=0,i=0,j=0; int step=array.length; while(true){ step=step/2; for(x=0;x=0 && array[j]>temp;j-=step){ array[j+step]=array[j]; } array[j+step]=temp; } } if(step==1){ break; } } printArray(array); } static void printArray(int[] array){ for(int val:array){ System.out.print(val+" "); } System.out.println(); }}
算法分析:希尔排序是一种不稳定的算法,单纯的插入排序是稳定的,希尔排序的空间复杂度为O(1),但是其时间复杂度:平均情况O(n^1.3)、最好情况O(n)、最坏情况难说,人们发明很多递增序列(也就是step取值)来渐进改进最坏情况下的比较次数(n^4/3,n^5/4,n^6/5......),这也说明,一个算法的出现,一定会有相应的优化策略。希尔排序和插入排序一样,同属初级排序算法。