1、基本思想
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。该方法实质上是一种分组插入方法。
2、图示
[img]http://dl2.iteye.com/upload/attachment/0113/1965/d150755f-d56f-3f8f-ac99-d4896205b158.png[/img]
3、Java代码实现
4、分析
前面分析过插入排序是稳定的,但经过多次插入排序后相同的元素的位置已经发生移动,最后稳定性会被打乱,所以希尔排序算法的实现是不稳定的。
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。该方法实质上是一种分组插入方法。
2、图示
[img]http://dl2.iteye.com/upload/attachment/0113/1965/d150755f-d56f-3f8f-ac99-d4896205b158.png[/img]
3、Java代码实现
package com.leiht.sort;
/**
* 希尔排序算法简单实现
* @author Leiht
*
*/
public class ShellSort {
public static void main(String[] args) {
int[] numbers = { 56, 45, 78, 67, 99, 13, 34, 49, 55, 34, 12, 77, 1 };
System.out.println("排序之前:");
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + " ");
}
//执行排序算法
new ShellSort().sort(numbers);
System.out.println();
System.out.println("排序之后:");
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + " ");
}
}
/**
* 排序方法
*
* @param numbers
*/
public void sort(int[] numbers) {
//定义分组1 d2 d3 ....dn dn= numbers.length / 2;
//目前效率较高的d的定义为 1,3 ,5. ... 2的K次方-1
int d = numbers.length / 2;
while (true) {
//每次 d = d /2
d = d / 2;
//第一次循环次数为0到d 代表总共分组的组数(一共有多少组)
for (int index = 0; index < d;index++) {
//循环第一组,增量为d,即【第i个,i+d, i+2d, i+3d....】为一组
//并按照直接插入排序对第一组进行排序,直到d=1,即对其完成直接排序
for (int i = index + d; i < numbers.length; i = i + d) {
int temp = numbers[i];
int j;
//循环从当前数据的前一个开始(如大于当前数据则向后移动一位即if(numbers[j] > temp) numbers[j + d] = numbers[j];)
//到有小于或等于当前数据止,跳出循环,将当前数据放到该位置即numbers[j + d] = temp;
for (j = i - d; j >= 0; j = j - d) {
if(numbers[j] > temp) {
numbers[j + d] = numbers[j];
}else {
break;
}
}
numbers[j + d] = temp;
}
}
if (d == 1) {
break;
}
}
}
}
4、分析
前面分析过插入排序是稳定的,但经过多次插入排序后相同的元素的位置已经发生移动,最后稳定性会被打乱,所以希尔排序算法的实现是不稳定的。