希尔排序
希尔排序是基本算法中的一种,最近在学习算法,前面学习了冒泡排序、插入排序、选择排序。这三种是比较简单的排序,有一种暴力算法的感觉,然而希尔排序却给人一种不一样的感觉,并不是一个一个循环过来的。首先先介绍一下希尔排序的算法逻辑。
- 将n个元素的数组分成2个大小为n/2的数组,这样就有n/2对数字,距离为n/2,将第一个与n/2 + 1个相比,以此类推。
- 循环进行排序替换使得每一对都有序。
- 再根据长度为n/2/2将数组拆分,进行循环排序。
- 重复以上动作。
例子如下:
原数组[67,64,17,93,87,22,80,23,97,54] length
= 10,所以d = 5,那么67跟22,64跟80一对等。
经过第一次排序:[22,64,17,93,54,67,80,23,97,87] d = 5 经过一次排序大家有没有发现距离为5的一对都是右边数字大。
经过第二次排序[17,23,22,64,54,67,80,87,97,93] d=5/2
= 2 这一步比较复杂,经过这次排序距离为2的都是右边数字大。
这里详细讲一下第二次排序,第二次排序首先比较a[2]跟a[0] -->a[3]跟a[1],最关键的是到a[4]的时候并不是只跟a[2]对比,
因为a[0]跟a[2]是有序的,所以现在的要求是将a[4]、a[2]、a[0]排成一个有序的3个数字。
经过第四次排序[17,22,23,64,54,67,80,87,93,97]
例子分析了,话不多说,上代码。
import java.text.SimpleDateFormat;
public class Solution {
public static void main(String[] agrs){
int[] a = new int[10];
for (int i = 0; i < 10; i++) {
a[i] = (int) (Math.random() * 100);
}
System.out.println("原数组--------------");
for (int i = 0; i < 10; i++) {
System.out.print(a[i] + ",");
}
System.out.println();
shellSort(a);
System.out.println("");
System.out.println("最终结果---------");
for (int i = 0; i < 10; i++) {
System.out.print(a[i] + ",");
}
}
public static int[] shellSort(int[] a) {
int x = 0;
for (int d = a.length / 2; d > 0; d /= 2) {
for (int j = d; j < a.length; j ++) {
int i = j;
int temp = a[j];
while (i > 0 && i - d >= 0 && a[i] < a[i - d]) {
a[i] = a[i - d];
i -= d;
}
a[i] = temp;
}
x++;
System.out.println("第" + x + "次排序距离d=" + d);
System.out.println("第" + x + "次排序结果。");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + ",");
}
System.out.println();
}
return a;
}
}
代码中自动生成了数组,并且打印了日志,希望有兴趣的同学可以理解希尔算法的奥秘指出,如有问题或疑问可以留言
指出。