排序算法(Java实现):Shell排序和归并排序
2011-11-30 23:15
393 查看
希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
步长的选择是希尔排序的重要部分。只要最终步长为1任何步长序列都可以工作。算法最开始以一定的步长进行排序。然后会继续以一定步长进行排序,最终算法以步长为1进行排序。当步长为1时,算法变为插入排序,这就保证了数据一定会被排序。
一直较好的增量序列是2^k-1,2^(k-1)-1,.....7,3,1,这样可使Shell排序时间复杂度达到O(N^1.5)。
为了方便扩展,先引入一个抽象的基础类:
归并排序,是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
归并操作的过程如下:
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
设定两个指针,最初位置分别为两个已经排序序列的起始位置
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针达到序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
归并排序算法源码如下:
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
步长的选择是希尔排序的重要部分。只要最终步长为1任何步长序列都可以工作。算法最开始以一定的步长进行排序。然后会继续以一定步长进行排序,最终算法以步长为1进行排序。当步长为1时,算法变为插入排序,这就保证了数据一定会被排序。
一直较好的增量序列是2^k-1,2^(k-1)-1,.....7,3,1,这样可使Shell排序时间复杂度达到O(N^1.5)。
为了方便扩展,先引入一个抽象的基础类:
package com.andyidea.algorithms; /** * 排序抽象基础类 * @author Andy.Chen * * @param <T> */ public abstract class Sorter<T extends Comparable<T>> { public abstract void sort(T[] array,int from,int len); public final void sort(T[] array){ sort(array,0,array.length); } protected final void swap(T[] array,int from,int to){ T tmp = array[from]; array[from] = array[to]; array[to] = tmp; } }希尔(Shell)排序算法源码如下:
package com.andyidea.algorithms; /** * 希尔(Shell)排序算法 * @author Administrator * * @param <T> */ public class ShellSort<T extends Comparable<T>> extends Sorter<T> { @Override public void sort(T[] array, int from, int len) { int value =1; while((value+1)*2 < len){ value = (value+1)*2 - 1; } for(int delta=value;delta<=1;delta=(delta+1)/2-1){ for(int i=0;i<delta;i++){ invokeInsertionSort(array,from,len,delta); } } } private final void invokeInsertionSort(T[] array,int from,int len,int delta){ if(len<=1) return; T tmp=null; for(int i=from+delta;i<from+len;i+=delta) { tmp=array[i]; int j=i; for(;j>from;j-=delta) { if(tmp.compareTo(array[j-delta])<0) { array[j]=array[j-delta]; } else break; } array[j]=tmp; } } }
归并排序,是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
算法描述
归并操作的过程如下:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
设定两个指针,最初位置分别为两个已经排序序列的起始位置
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针达到序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
归并排序算法源码如下:
package com.andyidea.algorithms; import java.lang.reflect.Array; /** * 归并排序法 * @author Andy.Chen * * @param <T> */ public class MergeSort<T extends Comparable<T>> extends Sorter<T> { @SuppressWarnings("unchecked") @Override public void sort(T[] array, int from, int len) { if(len<=1) return; T[] temp = (T[])Array.newInstance(array[0].getClass(), len); mergeSort(array, from, from+len-1, temp); } /** * 分成两组排序 * @param array * @param from * @param to * @param temporary */ private final void mergeSort(T[] array,int from,int to,T[] temporary){ if(to<=from) return; int middle = (from+to)/2; mergeSort(array, from, middle, temporary); mergeSort(array, middle+1, to, temporary); merge(array, from, to, middle, temporary); } /** * 把排序好的序列合并 * @param array * @param from * @param to * @param middle * @param temporary */ private final void merge(T[] array,int from,int to,int middle,T[] temporary){ int k=0; int leftIndex=0; int rightIndex=to-from; System.arraycopy(array, from, temporary, 0, middle-from+1); for(int i=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++; } } }
相关文章推荐
- JAVA实现排序算法(二):两种归并排序
- Java实现排序算法——归并排序
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 排序算法--归并排序Java实现 .
- Java实现-高效排序算法之Shell排序
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 排序算法复习(Java实现):插入,冒泡,选择,Shell,快速排序, 归并排序,堆排序,桶式排序,基数排序
- Java实现-高效排序算法之归并排序
- 排序算法总结(二)-------选择,堆,冒泡,快速,归并排序(java实现)
- 【常用排序算法】归并排序(Java实现)
- 算法 排序算法之归并排序 java实现
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 【排序算法】归并排序(java实现)
- 【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 排序算法(五):JAVA实现归并排序
- 排序算法--插入排序(直接插入排序、折半插入、shell排序)的java实现
- 排序算法的java实现-归并排序
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 【转】排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序