Shell Sort
排序算法——希尔排序
简单介绍
希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。
基本思想
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止
思路图解图

先根据不断分组来进行排序,最后当gap等于1进行插入排序
代码
算法代码
交换法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | 
 
 
 public static void shellSorting1 ( int[] arr ) {
 int x = 1;
 for ( int gap = arr.length / 2 ; gap > 0 ; gap /= 2 ) {
 int temp ;
 for ( int i = gap ; i < arr.length ; i++ ) {
 
 for ( int j = i - gap ; j >= 0 ; j -= gap ) {
 if ( arr[ j ] > arr[ j + gap ] ) {
 temp           = arr[ j ];
 arr[ j ]       = arr[ j + gap ];
 arr[ j + gap ] = temp;
 }
 }
 }
 System.out.println ( "希尔排序第" + ( x++ ) + "轮" + Arrays.toString ( arr ) );
 }
 System.out.println ("交换法排序后"+ Arrays.toString (arr));
 }
 
 | 
移动法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 
 | 
 
 
 public static void shellSorting2 ( int[] arr ) {
 
 for ( int gap = arr.length / 2 ; gap > 0 ; gap /= 2 ) {
 
 for ( int i = gap ; i < arr.length ; i++ ) {
 int j = i;
 int temp = arr[j];
 if ( arr[ j ] < arr[ j - gap ] ) {
 while (j-gap >= 0 && temp < arr[ j-gap ] ) {
 arr[ j ] = arr[ j - gap ];
 j -= gap;
 
 }
 
 
 arr[ j ] = temp;
 
 }
 
 }
 }
 System.out.println ("移动法排序后"+ Arrays.toString (arr));
 }
 
 | 
性能测试
依旧是用80000个数来进行排序比较时间
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 
 | public class ShellSorting {public static void main ( String[] args ) {
 
 
 int arr[] = new int[ 80000 ];
 int arr1[] = new int[ 80000 ];
 randomArr ( arr );
 randomArr ( arr1 );
 
 System.out.println ("希尔排序交换法所用时间" );
 String date1String = Date ( );
 System.out.println ("排序前时间是:"+date1String );
 shellSorting1 ( arr );
 String date2String = Date ( );
 System.out.println ("排序后时间是:"+date2String );
 
 System.out.println ("希尔排序移动法所用时间" );
 String date3String = Date ( );
 System.out.println ("排序前时间是:"+date3String );
 shellSorting2 ( arr1 );
 String date4String = Date ( );
 System.out.println ("排序后时间是:"+date4String );
 }
 
 
 
 
 
 
 public static void shellSorting2 ( int[] arr ) {
 
 for ( int gap = arr.length / 2 ; gap > 0 ; gap /= 2 ) {
 
 for ( int i = gap ; i < arr.length ; i++ ) {
 int j = i;
 int temp = arr[j];
 if ( arr[ j ] < arr[ j - gap ] ) {
 while (j-gap >= 0 && temp < arr[ j-gap ] ) {
 arr[ j ] = arr[ j - gap ];
 j -= gap;
 
 }
 
 
 arr[ j ] = temp;
 
 }
 
 }
 }
 
 }
 
 
 
 
 
 public static void shellSorting1 ( int[] arr ) {
 int x = 1;
 for ( int gap = arr.length / 2 ; gap > 0 ; gap /= 2 ) {
 int temp ;
 for ( int i = gap ; i < arr.length ; i++ ) {
 
 for ( int j = i - gap ; j >= 0 ; j -= gap ) {
 if ( arr[ j ] > arr[ j + gap ] ) {
 temp           = arr[ j ];
 arr[ j ]       = arr[ j + gap ];
 arr[ j + gap ] = temp;
 }
 }
 }
 
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }
 
 
 
 
 private static void randomArr ( int[] arr ) {
 for(int i = 0; i < arr.length;i++){
 arr[ i ] = (int) ( Math.random ( ) * 8000000 );
 }
 }
 
 
 
 
 
 private static String Date ( ) {
 Date date1 = new Date ( );
 SimpleDateFormat simpleFormatter = new SimpleDateFormat ( "HH:mm:ss" );
 return simpleFormatter.format(date1 );
 }
 }
 
 | 
结果
两种方法进行比较,时间差距十分的大
