常见排序算法——希尔排序
Posted sdx-bk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常见排序算法——希尔排序相关的知识,希望对你有一定的参考价值。
希尔排序:
希尔排序是对插入排序的优化,将插入排序的交换步长由1增加到h。
希尔排序的思想是使数组中任意间隔为h的元素有序。步长调幅为h = 3*h + 1, 也就是1,4,13,40,121,364, 1003....这种步长算法是经过论文证明为比较高效的步长。
最开始由最大步长开始排序,最大步长为
while(h < n/3) h = 3*h +1
步长最大时,比较的元素非常少,速度很快
后来步长逐渐缩短,比较的元素越来越多,但是此时元素的有序性也变好了,排序速度还是会很快。
while(h>=1){
for: i from h~n{
for: j from i~h,j = j-h;
比较a[j]和a[j-h],并根据比较结果交换元素位置,
}
}
实现代码:()
import java.util.Arrays;
import java.util.Random;
public class ShellSort {
1.这是定义了一个公共的(public)静态的(static )泛型方法
其中<AnyType extends Comparable<? super AnyType>>是泛型的类型,定义类型只能是Comparable或Comparable的子类,并且Comparable也是一个泛型类他的 类型只能是AnyType或是AayType的超类也就是AayType父类
int 是方法的返回类型
(AnyType[] a,AnyType x)参数列表,第一个是传递进来的数组第二个是一个值,也就是查找该值在数组中的下标,他们的类型都是该泛型方发传进来的类型
public static <AnyType extends Comparable<? super AnyType>>
void shellSortOnce(AnyType a[]){
AnyType temp;
if((a==null)||(a.length==0)){
return ;
}
for(int gap = a.length /2 ; gap > 0 ;gap = gap /2){
for(int i = gap ; i<a.length; i++){
AnyType tmp = a[i];
int j = i;
for( ; j >= gap && tmp.compareTo(a[j - gap]) < 0 ; j -= gap){
a[j] = a[j-gap];
}
a[j] = tmp ;
}
}
}
public static void main(String[] args){
Random rand = new Random();
Integer[] arr = new Integer[10];
for(int i = 0 ;i <10 ;i++){
arr[i] = rand.nextInt(1000);
}
println(Arrays.toString(arr));
shellSortOnce(arr);
println(Arrays.toString(arr));
}
public static void println(String str){
System.out.println(str);
}
}
}
import java.util.Arrays;
import com.edu.hpu.sort.Sort;
public class ShellSort extends Sort {
@Override
public int[] doSort(int[] arr) {
int len = arr.length;
// 所有的步长可能性(首次为数组长的一半,接下来每次为上一次的一半)
for (int gap = len / 2; gap > 0; gap /= 2) {
// 将步长中的所有元素进行插入排序
for(int w = 0; w < gap; w++){
// 步长为gap的插入排序
// 对照插入排序
/*
* for(int i = p + 1; i < r; i++){
* int key = arr[i];
* int j = i - 1;
* while(j >= 0 && arr[j] > key) {
* arr[j + 1] = arr[j];
* j--;
* }
* arr[j + 1] = key;
* }
*/
for (int i = gap + w; i < len; i += gap) {
// 插入排序
int key = arr[i];
int j = i - gap;
while (j >= 0 && arr[j] > key) {
arr[j + gap] = arr[j];
j -= gap;
}
arr[j + gap] = key;
}
}
System.out.println(Arrays.toString(arr));
}
return arr;
}
public static void main(String[] args) {
Sort sort = new ShellSort();
sort.printOrder(new int[] {100, 201, 999, 4, 1, 3, 2, 16, 9, 100, 194, 8, 7, 0, 90 });
}
}
}
package www.jk.shell;
import java.util.Arrays;
public class Test {
/**
* @author jk,这个代码写的是shell排序,其实我个人认为这个排序的思想是把归并和快排的思想结合起来,快排是通过
* 第一个元素来进行左右划分,归并是无论什么样,先将数组分成两组,然后继续分最后结合起来,这个shell排序,首先是将数组
* 分为两组,然后进行插入,其实就类似将大的或者小的先放在前面或者后面,所以,我认为这个算法的复杂度应该和归并和快排是差不多的
*
*/
public static void main(String[] args) {
int[] a = { 1, 4, 2, 0, 8, 6, 4, 6 };
shellSort(a);
// 输出排序后的数组
System.out.println(Arrays.toString(a));
}
private static void shellSort(int[] a) {
// 将数组分组
for (int r = a.length / 2; r >= 1; r /= 2) {
// 这里的思路和插入排序的思路相同,通过找到前一个的数大于或者小于来进行插入
for (int i = r; i < a.length; i += r) {
int temp = a[i];
int j = i - r;
while (j >= 0 && temp < a[j]) {
a[j + r] = a[j];
j -= r;
}
a[j + r] = temp;
}
}
}
}
以上是关于常见排序算法——希尔排序的主要内容,如果未能解决你的问题,请参考以下文章