Java--Shell(希尔)排序

**Shell排序的执行时间依赖于增量序列。
好的增量序列的共同特征:
① 最后一个增量必须为1;
② 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。
希尔排序的时间性能优于直接插入排序的原因:

①当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。

②当n值较小时,n和n^2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(n^2)差别不大。

③在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。

因此,希尔排序在效率上较直接插入排序有较大的改进。

折叠稳定性

希尔排序是不稳定的。参见上述实例,该例中两个相同关键字49在排序前后的相对次序发生了变化。
**
我们先来了解一下直接插入排序:

public static void insertSort(int[] array){
        int tmp=0;
        int i=1;
        int j=0;
        for(i=1;i<array.length;i++){
            tmp=array[i];
            for(j=i;j>=0;j--){
                if(array[j]>tmp){
                array[j+1]=array[j];    
                }else{
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

输入:
输出:
视图分析:
Shell排序举例:
先给一个含15个元素的数组:

int[] array={12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};

1、按以下方式将它分为五组,每组三个元素:
这里写图片描述
2、每组内进行直接插入排序如下:
这里写图片描述
3、将排序好的序列分为三组,每组五个元素:
这里写图片描述
4、同上,组内进行直接插入排序如下:
这里写图片描述
5、最后整个序列为一组并进行直接插入排序:
这里写图片描述
代码:

package YuanChuang;

import java.util.Arrays;

/*
 * 直接插入排序:越有序越好排
 * Shell(希尔)排序:采用分组的策略,让组内有序,
 * 
 * */
public class ZhiJie {
    public static void insertSort(int[] array){
        int tmp=0;
        int i=1;//计数
        int j=0;//计数
        for(i=1;i<array.length;i++){//对序列进行遍历,从第一个元素开始
            tmp=array[i];//把array[i]放入tmp中
            for(j=i;j>=0;j--){
                if(array[j]>tmp){
                array[j+1]=array[j];    
                }else{
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }
    //相当于直接插入排序
    public static void shell(int[] array,int gap){//gap分组
        int tmp = 0;
        int j = 0;//计数
        for(int i = gap;i < array.length;i++){
            tmp = array[i];
            for(j = i-gap;j >= 0;j -= gap){
                if(array[j]>tmp){
                    array[j+gap]=array[j];
                }else{
                    break;
                }
            }
            array[j+gap] = tmp;
        }
    }

    public static void shellSort(int[] array){
        int[] d = {5,3,1};//5、3、1相当于给shell中传进的 gap
        for(int i = 0;i < d.length;i++){
            shell(array,d[i]);//调用shell方法
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] array={12,5,9,34,6,8,33,56,89,0,7,4,22,55,77};
        shellSort(array);
        System.out.println(Arrays.toString(array));
    }

}

输出结果为:
这里写图片描述
可见,与我们们用图推出来的结果相同。完美~~

阅读更多
个人分类: Java
上一篇Java -- 链式队列和优先队列
下一篇Java--快速排序
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭