文章目录
前言
冒泡排序,选择排序、插入排序,在最坏情况下的时间复杂度都是O(N^2),随着输入规模的增大,时间成本将急剧上升,所以冒泡排序,选择排序、插入排序不能处理大规模的问题
一. 希尔排序
1.1 排序原理
希尔排序是插入排序的一种,是插入排序算法的一种更高效的改进版本。
1.选定一个增长量h,按照增长量h作为数据分组的依据,对数据进行分组;
2.对分好组的每一组数据完成插入排序;
3.减小增长量,最小减为1,重复第二步操作。
增长量h的确定:
int h = 1;
while (h < 数组长度/2) {
h=2*h+1;
}
//循环结束后就可以确定h的最大值;
//h的减小规则为: h=h/2
1.2 希尔排序api设计和代码实现
类名 | Shell |
---|---|
构造方法 | Shell():创建Shell对象 |
成员方法:
public static void sort(Comparable[] a):对数组内的元素进行排序 ;
private static boolean greater(Comparable v,Comparable w):判断v是否大于w;
private static void exch(Comparable[] a,int i,int j):交换a数组中,索引i和索引j处的值
public class Shell {
public static void sort(Comparable[] a) {
/*第一步,根据数组的长度,确定增长量h*/
int h = 1;
while (h < a.length / 2) {
h = 2 * h + 1;
}
/*希尔排序*/
while (h >= 1) {
//排序
//找到待插入的元素
for (int i = h; i < a.length; i++) {
//把待插入的元素插入到有序数列中
for (int j = i; j >= h; j -= h) {
//待插入的元素为a[j],比较a[j]和a[j-h]
if (greater(a[j - h], a[j])) {
exch(a, j - h, j);
} else {
//待插入元素已经找到合适的位置,结束循环
break;
}
}
}
//缩小增长量
h /= 2;
}
}
private static boolean greater(Comparable v, Comparable w) {
return v.compareTo(w) > 0;
}
private static void exch(Comparable[] a, int i, int j) {
Comparable temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
1.3 测试
public static void main(String[] args) {
Integer[] a = {4, 6, 8, 7, 9, 2, 10, 1};
Shell.sort(a);
System.out.println(Arrays.toString(a));
}
1.4 希尔排序的时间复杂度分析
在希尔排序中,增长量h并没有固定的规则,有很多论文研究了各种不同的递增序列,但无法证明某个序列是最好的,对于希尔排序的时间复杂度分析,需要进一步研究
二.
2.1
2.2
2.3
三.
3.1
3.2
3.3