希尔排序 Shell Sort
缩小增量排序。
简单插入排序的改进高效版本。
把记录 按 下标的增量 一个一个分组。
相比于插入排序改进点
间隔大的时候,移动次数少。
间隔小的时候,移动距离比较短。
首先给一个间隔
其次缩小间隔
直到间隔为1
图解
10个数,10/2,分为5组
利用步长 8 和 3一组
9 和 5 一组
以此类推
每组之间交换,8和3交换
5和9交换
1和4不发生交换
7和6交换
2和0交换
目的:尽快让小的数,往前移动
5个数,5/2分为2组
3 1 5 9 7
5 6 8 4 2
这两组,进行调整
0 1 3 7 9
2 4 5 6 8
0214357698
2/2 = 1
013456789
总结组数变化; 5–2—1
题目
有一群小牛,考试成绩分别是 {8,9,1,7,2,3,5,4,6,0}请从小到大排序.请分别使
用
理解
首先
1)希尔排序时,对有序序列在插入时采用交换法,并测试排序速度。
2)希尔排序时,对有序序列在插入时采用移动法,并测试排序速度。
交换法
package sort;
import java.util.Arrays;
public class ShellSort {
public static void main(String[] args) {
//
int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
shellSort(arr);
}
public static void shellSort(int[] arr) {
System.out.println("原始数组: " + Arrays.toString(arr));
// 希尔排序的第1轮排序
// 第一轮循环,将10个数,分为5组
for (int i = 5; i < arr.length; i++) {
// 遍历各组中所有的元素
// 遍历各组中所有元素(共5组,每组2个),步长为5
for (int j = i - 5; j >= 0; j -= 5) {
// 如果当前元素 大于 + 步长后的元素,说明 交换
if (arr[j] > arr[j + 5]) {
int temp = arr[j];
arr[j] = arr[j + 5];
arr[j + 5] = temp;
}
}
}
System.out.println("一轮数组: " + Arrays.toString(arr));
//希尔排序第二轮,将10个数组分为 5/2 = 2 组
for (int i = 2; i < arr.length; i++) {
// 遍历各组中所有的元素
// 遍历各组中所有元素(共5组,每组2个),步长为5
for (int j = i - 2; j >= 0; j -= 2) {
// 如果当前元素 大于 + 步长后的元素,说明 交换
if (arr[j] > arr[j + 2]) {
int temp = arr[j];
arr[j] = arr[j + 2];
arr[j + 2] = temp;
}
}
}
System.out.println("二轮数组: " + Arrays.toString(arr));
//希尔排序第三轮,将10个数组分为 2/2 = 1 组
for (int i = 1; i < arr.length; i++) {
// 遍历各组中所有的元素
// 遍历各组中所有元素(共5组,每组2个),步长为5
for (int j = i - 1; j >= 0; j -= 1) {
// 如果当前元素 大于 + 步长后的元素,说明 交换
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("三轮数组: " + Arrays.toString(arr));
}
}
原始数组: [8, 9, 1, 7, 2, 3, 5, 4, 6, 0]
一轮数组: [3, 5, 1, 6, 0, 8, 9, 4, 7, 2]
二轮数组: [0, 2, 1, 4, 3, 5, 7, 6, 9, 8]
二轮数组: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
整理
package sort;
import java.util.Arrays;
public class ShellSort {
public static void main(String[] args) {
//
int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
shellSort(arr);
}
public static void shellSort(int[] arr) {
System.out.println("原始数组: " + Arrays.toString(arr));
int temp = 0;
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
// 遍历各组中所有元素(共gap组),步长为gap
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(gap);
System.out.printf("轮数组: " + Arrays.toString(arr) + "\n");
}
}
}
or 这么写
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void shellSort3(int[] arr) {
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < arr.length; i++) {
for (int j = i; j > gap - 1; j -= gap) {
if (arr[j] < arr[j - gap]) {
swap(arr, j, j - gap);
}
}
}
}
System.out.println(Arrays.toString(arr));
交换式希尔排序优化—>移位法