转载http://blog.csdn.net/cjjky/article/details/7029141
希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
- 插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
- 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
步长的选择是希尔排序的重要部分。只要最终步长为1任何步长序列都可以工作。算法最开始以一定的步长进行排序。然后会继续以一定步长进行排序,最终算法以步长为1进行排序。当步长为1时,算法变为插入排序,这就保证了数据一定会被排序。
一直较好的增量序列是2^k-1,2^(k-1)-1,.....7,3,1,这样可使Shell排序时间复杂度达到O(N^1.5)。
为了方便扩展,先引入一个抽象的基础类:
- packagecom.andyidea.algorithms;
- /**
- *排序抽象基础类
- *@authorAndy.Chen
- *
- *@param<T>
- */
- publicabstractclassSorter<TextendsComparable<T>>{
- publicabstractvoidsort(T[]array,intfrom,intlen);
- publicfinalvoidsort(T[]array){
- sort(array,0,array.length);
- }
- protectedfinalvoidswap(T[]array,intfrom,intto){
- Ttmp=array[from];
- array[from]=array[to];
- array[to]=tmp;
- }
- }
- packagecom.andyidea.algorithms;
- /**
- *希尔(Shell)排序算法
- *@authorAdministrator
- *
- *@param<T>
- */
- publicclassShellSort<TextendsComparable<T>>extendsSorter<T>{
- @Override
- publicvoidsort(T[]array,intfrom,intlen){
- intvalue=1;
- while((value+1)*2<len){
- value=(value+1)*2-1;
- }
- for(intdelta=value;delta<=1;delta=(delta+1)/2-1){
- for(inti=0;i<delta;i++){
- invokeInsertionSort(array,from,len,delta);
- }
- }
- }
- privatefinalvoidinvokeInsertionSort(T[]array,intfrom,intlen,intdelta){
- if(len<=1)
- return;
- Ttmp=null;
- for(inti=from+delta;i<from+len;i+=delta)
- {
- tmp=array[i];
- intj=i;
- for(;j>from;j-=delta)
- {
- if(tmp.compareTo(array[j-delta])<0)
- {
- array[j]=array[j-delta];
- }
- elsebreak;
- }
- array[j]=tmp;
- }
- }
- }
算法描述
归并操作的过程如下:
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针达到序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
- packagecom.andyidea.algorithms;
- importjava.lang.reflect.Array;
- /**
- *归并排序法
- *@authorAndy.Chen
- *
- *@param<T>
- */
- publicclassMergeSort<TextendsComparable<T>>extendsSorter<T>{
- @SuppressWarnings("unchecked")
- @Override
- publicvoidsort(T[]array,intfrom,intlen){
- if(len<=1)
- return;
- T[]temp=(T[])Array.newInstance(array[0].getClass(),len);
- mergeSort(array,from,from+len-1,temp);
- }
- /**
- *分成两组排序
- *@paramarray
- *@paramfrom
- *@paramto
- *@paramtemporary
- */
- privatefinalvoidmergeSort(T[]array,intfrom,intto,T[]temporary){
- if(to<=from)
- return;
- intmiddle=(from+to)/2;
- mergeSort(array,from,middle,temporary);
- mergeSort(array,middle+1,to,temporary);
- merge(array,from,to,middle,temporary);
- }
- /**
- *把排序好的序列合并
- *@paramarray
- *@paramfrom
- *@paramto
- *@parammiddle
- *@paramtemporary
- */
- privatefinalvoidmerge(T[]array,intfrom,intto,intmiddle,T[]temporary){
- intk=0;
- intleftIndex=0;
- intrightIndex=to-from;
- System.arraycopy(array,from,temporary,0,middle-from+1);
- for(inti=0;i<to-middle;i++){
- temporary[to-from-i]=array[middle+i+1];
- }
- while(k<to-from+1){
- if(temporary[leftIndex].compareTo(temporary[rightIndex])<0)
- {
- array[k+from]=temporary[leftIndex++];
- }
- else
- {
- array[k+from]=temporary[rightIndex--];
- }
- k++;
- }
- }
- }