您的位置:首页 > 编程语言 > Java开发

java排序算法(3)—希尔排序

2017-03-07 00:36 267 查看

1、概述

排序就是将一组对象按照某种逻辑顺序重新排列的过程。

希尔排序是基于插入排序的的快速排序算法。对于大规模乱序排序数组插入排序很慢,因为它只会交换相邻的元素,例如,如果主键最小的元素正好在数组的尽头,要将它挪到正确位置就要就需要N-1次移动。希尔排序为了加快速度简单地改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。

希尔排序基本思想:

(1)h为初始增量,取值范围,1 < h < N(1,4,13,121,364…) 。先从data[0]开始,以h为增量进行直接插入排序,直到数组末尾;

(2)然后从data[1]开始,重复(1)过程,直到data[n-h];

(3)然后取一个小于上一步增量的新增量(如:h/2)。对上两个步骤重复,直到新的变量小于1之后退出循环。

2、代码实现

package com.chunsoft.sort;

public class SheelSort {
public static void main(String[] args) {
int data[] = {9,0,7,6,5,8,3,2,1};
F_ShellSort(data);
for(int num :data) {
System.out.println(num);
}
}

private static void F_ShellSort(int[] data) {
int N = data.length;
//边界验证
if(data == null ||  N <= 0) {
return;
}
//初始增量
int h = 1;
while(h < N/3) h = 3*h + 1;
while(h >= 1)
{
//将数组变为h有序
for(int i = 0;i < N;i ++) {
//将a[i]插入到a[i+h],a[i+2*h],a[i+3*h]...之中
for(int j = i;j < N - h;j = j + h){
if(data[j] > data[j+h]) {
int temp = data[j];
data[j] = data[j+h];
data[j+h] = temp;
}
}
}
//设置新的增量
h = h/2;
}
}
}


3、复杂度和稳定性

(1)复杂度

希尔排序的关键并不是随便分组后各自排序,而是将相隔某个“增量”的记录组成一个子序列,实现跳跃式移动,使得排序的效率提高。需要注意的是,增量序列的最后一个增量值必须等于1才行。

时间复杂度:最好时间复杂度和平均复杂度O(N*log(N)),最坏时间复杂度O(N*N)

空间复杂度:O(1)

(2)稳定性

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。

不稳定的:

由于希尔排序的元素是跳跃式的移动,因此希尔排序并不是一种未定的排序算法。

(3)特点

针对大规模乱序数组排序速度较快。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息