java算法之四希尔排序(插入排序)
2016-01-26 11:39
639 查看
希尔排序:
* 基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。
* 所有距离为dl的倍数的记录放在同一个组中。
* 先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,
* 直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
* 该方法实质上是一种分组插入方法。
演示地址:http://student.zjzk.cn/course_ware/data_structure/web/flashhtml/shell.htm
自己的code:
网上版本的code:
运行测试结果:
希尔排序(缩小增量法)
属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序。希尔排序并不稳定,O(1)的额外空间,时间复杂度为O(N*(logN)^2)。最坏的情况下的执行效率和在平均情况下的执行效率相比相差不多。且较依赖分割值。(splitNum)
* 基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。
* 所有距离为dl的倍数的记录放在同一个组中。
* 先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,
* 直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
* 该方法实质上是一种分组插入方法。
演示地址:http://student.zjzk.cn/course_ware/data_structure/web/flashhtml/shell.htm
自己的code:
import java.util.ArrayList; public class shellSort { private static int[] array ={49,38,65,97,76,13,27,49,55,04}; public static void main(String[] args) { int[] splitNum = {5,3,1}; for(int i=0;i<splitNum.length;i++){ shellsort(array, splitNum[i]); for(int j=0;j<array.length;j++) { System.out.print(array[j]+","); } System.out.println(""); } } //直接插入排序 public static int[] insertSorts(int[] array) { if(array == null || array.length < 2){ return array; } for(int i=1;i<array.length;i++) { int currentValue = array[i]; int position = i; for(int j=i-1;j>=0;j--) { if(array[j]>currentValue){ array[j+1] = array[j]; --position; } else { break; } } array[position] = currentValue; } return array; } //希尔排序 public static void shellsort(int[] array, int splitNum) { if(array == null || array.length < 2){ return; } //分组排序 for(int k=0;k<splitNum;k++){ //将分组的数字合成一个新数组,并排序 ArrayList<Integer> tempArrayList = new ArrayList<Integer>(); for(int i=0;i<((array.length/(double)splitNum));i++) { if(i*splitNum+k < array.length){ //避免越界 tempArrayList.add(array[i*splitNum+k]); } } Integer[] tempArray = new Integer[tempArrayList.size()]; tempArray = tempArrayList.toArray(tempArray); //将排好序的新数组重新赋值给原先分组对应的位置 int[] tempArrayInt = toIntArray(tempArray); for(int i=0;i<tempArrayList.size();i++){ int[] arr = insertSorts(tempArrayInt); array[i*splitNum+k] = arr[i]; } } } //将Integer数组 转成 int数组 public static int[] toIntArray(Integer[] arr){ int n=arr.length; int[] iarr=new int ; for(int i=0;i<n;i++){ iarr[i] = arr[i].intValue(); } return iarr; } }
网上版本的code:
public class ShellSort { private int[] intArray; // 待排序的数组 private int nItems; // 数组内元素个数 private int maxItems; // 数组大小 private int[] intervalSequence; // 增量数组序列 // 构造函数 public ShellSort( int maxItems, int[] intervalSequence ) { this.intArray = new int[maxItems]; this.maxItems = maxItems; this.nItems = 0;// 还没有元素 this.intervalSequence = intervalSequence; } /** * 49 38 65 97 76 13 27 49 55 4 * * 希尔排序算法,从小到大 */ public void shellSortMethod() { int h = 0;//为增量 for ( int iIntervalLength = 0; iIntervalLength < intervalSequence.length; iIntervalLength++ )//最外层循环,由增量序列元素个数决定 { h = intervalSequence[iIntervalLength];//h为index增量 int sizeInterArray;//每次内部插入排序的元素个数 if ( 0 == nItems % h ) { sizeInterArray = nItems/h; } else { sizeInterArray = nItems/h + 1; } for ( int jZeroToH = 0; jZeroToH < h; jZeroToH++ )//index从 0->h-1 共h-1次循环 { int temp = 0; int out = 0,in = 0; /** * 例如: * 当h=3,intArray.lenght=10时,sizeInterArray初始化为4, * 当jZeroToH=1,此时的内部插入排序元素index=1,4,7,为3个元素, * 所以应该进行判断,以适应内部插入排序元素减少的情况 */ if ( jZeroToH+(sizeInterArray-1)*h >= nItems ) { sizeInterArray--; } // 内部用插入排序 // 最大有sizeInterArray个元素有待排序 for ( int i = 1; i < sizeInterArray; i++ )// 总共有sizeInterArray个元素有待排序,所以循环sizeInterArray次 { out = jZeroToH + i * h; temp = intArray[out]; in = out; while ( in > h-1 && intArray[in - h] > temp ) { intArray[in] = intArray[in-h]; in = in - h; } intArray[in] = temp; } } System.out.print(iIntervalLength + " : h=" + h + " "); this.displayArray(); } } // 插入一个元素到待排序数组 public void insert( int value ) { if ( nItems < maxItems ) { intArray[nItems] = value; nItems++ ; } else { System.out.println( "The array is full!" ); } } //初始化待排序数组 public void initArray( int[] array ) { for ( int i = 0; i < array.length; i++ ) { intArray[i] = array[i]; } nItems = array.length; } //用随机数初始化 public void initRandom() { nItems = 0; for ( int i = 0; i < maxItems; i++ ) { int n = (int) ( java.lang.Math.random( ) * maxItems ); insert( n ); } } // 显示数组内容 public void displayArray() { System.out.print( "\t" ); for ( int i = 0; i < nItems; i++ ) { System.out.print( intArray[i] + " " ); } System.out.println( "" ); } } 测试程序: package zieckey.datastructure.study.sort; public class ShellSortApp { /** * @param args */ public static void main( String[] args ) { int[] intervalSequence = { 5, 3, 1 }; int[] array = { 49, 38, 65, 97, 76, 13, 27, 49, 55, 04 }; ShellSort ss = new ShellSort( array.length, intervalSequence ); ss.initArray( array );//初始化待排序数组 System.out.print("Init array: "); ss.displayArray(); ss.shellSortMethod();//排序 System.out.print("Sorted array: "); ss.displayArray(); } }
运行测试结果:
13,27,49,55,4,49,38,65,97,76, 13,4,49,38,27,49,55,65,97,76, 4,13,27,38,49,49,55,65,76,97,
希尔排序(缩小增量法)
属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序。希尔排序并不稳定,O(1)的额外空间,时间复杂度为O(N*(logN)^2)。最坏的情况下的执行效率和在平均情况下的执行效率相比相差不多。且较依赖分割值。(splitNum)
相关文章推荐
- Java 入门 之 静态函数与静态变量
- Spring Data JPA 动态查询
- 十进制转化为二进制
- SpringMVC深度探险(二) —— SpringMVC概览
- J2EE框架(Struts&Hibernate&Spring)的理解
- Eclipse CDT gcc 报错 对‘exp’未定义的引用
- Spring事务异常回滚,捕获异常不抛出就不会回滚
- java.lang.OutOfMemoryError:GC overhead limit exceeded解决方法
- java代码转dll文件
- myeclipse中weblogic开启debug跳到class文件问题
- background indexer crash recovery java.lang.stackoverflowerror
- java中的socket编程
- Spring之FactoryBean
- Java工程师成神之路
- java多线程经典题目
- javamail 收邮件并解析附件
- eclipse CDT gcc g++ 参数
- Spring+Websocket实现消息的推送 【转】
- java多线程之龟兔赛跑问题
- Java时间日期相关开发