java数据结构与算法之希尔排序_希尔排序csdn

createh53周前 (02-26)技术教程3

希尔排序概述

希尔排序因计算机科学家Donald1.Shell而得名,他在1959年发现了希尔排序算法。希尔排序基于插入排序,但是增加了一个新的特性,大大地提高了插入排序的执行效率。

依靠这个特别的实现机制,希尔排序对于多达几千个数据项的,中等大小规模的数组序表现良好。希尔排序不像快速排序和其他时间复杂度为O(N*IogN)的排序算法那么快,因此对非常大的文件排序,它不是最优选择。但是,希尔排序比选择排序和插入排序这种时间复杂度为O(n^2)的排序算法还是要快得多,并且它非常容易实现:希尔排序算法的代码既短又简单。

它在最坏情况下的执行效率和在平均情况下的执行效率相比没有差很多。一些专家提倡差不多任何排序工作在开始时都可以使用希尔排序算法,若在实际中证明它不够快,再改换成诸如快速排序这样更高级的排序算法。

希尔排序过程图示

希尔排序目的为了加快速度改进了插入排序,交换不相邻的元素对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。

在此我们选择增量 gap=length/2,缩小增量以 gap = gap/2 的方式,用序列 {n/2,(n/2)/2...1} 来表示。

如图示例:

(1)初始增量第一趟 gap = length/2 = 4

希尔排序java代码

//--------------------------------------------------------------
class ArraySh {
    private long[] theArray; // ref to array theArray
    private int nElems; // number of data items

    //--------------------------------------------------------------
    public ArraySh(int max) // constructor
    {
        theArray = new long[max]; // create the array
        nElems = 0; // no items yet
    }

    //--------------------------------------------------------------
    public void insert(long value) // put element into array
    {
        theArray[nElems] = value; // insert it
        nElems++; // increment size
    }

    //--------------------------------------------------------------
    public void display() // displays array contents
    {
        System.out.print("A=");
        for (int j = 0; j < nElems; j++) // for each element,
            System.out.print(theArray[j] + " "); // display it
        System.out.println("");
    }

    //--------------------------------------------------------------
    public void shellSort() //希尔排序核心代码
    {
        int inner, outer;
        long temp;
        int h = 1; // find initial value of h
        while (h <= nElems / 3) {
         h = h * 3 + 1; // (1, 4, 13, 40, 121, ...)产 生隔
        }
        while (h > 0) // decreasing h, until h=1
        {
            // h-sort the file
            for (outer = h; outer < nElems; outer++) {
                temp = theArray[outer];
                inner = outer;
                // one subpass (eg 0, 4, 8)
                while (inner > h - 1 && theArray[inner - h] >= temp) {
                    theArray[inner] = theArray[inner - h];
                    inner -= h;
                }
                theArray[inner] = temp;
            } // end for
            h = (h - 1) / 3; // decrease h(...,121,40,13,4,1)减少隔
        } // end while(h>0)
    } // end shellSort()
//--------------------------------------------------------------
} // end class ArraySh

////////////////////////////////////////////////////////////////
class ShellSortApp {
    public static void main(String[] args) {
        int maxSize = 10; // array size
        ArraySh arr;
        arr = new ArraySh(maxSize); // create the array
        for (int j = 0; j < maxSize; j++) // fill array with
        { // random numbers
            long n = (int) (java.lang.Math.random() * 99);
            arr.insert(n);
        }
        arr.display(); // display unsorted array
        arr.shellSort(); // shell sort the array
        arr.display(); // display sorted array
    } // end main()
} // end class ShellSortApp
////////////////////////////////////////////////////////////////

希尔排序效率

希尔排序时间复杂度是 O(n^(1.3-2)),空间复杂度为常数阶 O(1)。希尔排序没有时间复杂度为 O(n(logn)) 的快速排序算法快 ,因此对中等大小规模表现良好,但对规模非常大的数据排序不是最优选择,总之比一般 O(n^2 ) 复杂度的算法快得多。

相关文章

Java常用的7大排序算法汇总_java常见的排序算法

这段时间闲了下来,就抽了点时间总结了下java中常用的七大排序算法,希望以后可以回顾!1.插入排序算法插入排序的基本思想是在遍历数组的过程中,假设在序号 i 之前的元素即 [0..i-1] 都已经排好...

JAVA 冒泡排序_Java冒泡排序法

1 概念冒泡排序(Bubble Sort),是计算机科学领域中较简单的一种排序算法。它重复地走访需要进行排序的元素,依次比较两个相邻的元素,如果元素的顺序(如从大到小、首字母从A到Z)错误就把元素的位...

堆排序实战:轻松实现高效排序,附详细Java代码

#每日读书打卡#Hello,大家好!我是你们的小米,今天又来给大家分享干货啦!最近很多小伙伴们都对排序算法产生了浓厚的兴趣,继上次分享了“手写快排”之后,今天我们再来搞搞堆排(Heap Sort),...

八种经典排序算法总结,妈妈再也不用担心我不会了

前言算法和数据结构是一个程序员的内功,所以经常在一些笔试中都会要求手写一些简单的排序算法,以此考验面试者的编程水平。下面我就简单介绍八种常见的排序算法,一起学习一下。一、冒泡排序思路:比较相邻的元素。...

深圳尚学堂Java培训:排序方法小结-插入排序

插入排序工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。就是将数组第一个值看做有序的,从后每一个值放进来的时候,找放的位置。这里边就需要一些已经排好的数据可...