1。前言 本节内容是排序算法系列之一:希尔排序,主要讲解了希尔排序的主体思路,选取了一个待排序的数字列表对希尔排序算法进行了演示,给出了希尔排序算法的Java代码实现,帮助大家可以更好的理解希尔排序算法。2。什么是希尔排序? 希尔排序(ShellSort),是计算机科学与技术领域中较为简单的一种排序算法。 希尔排序是插入排序的一种,有时候也被称为缩小增量排序。它是插入排序的改进版,与插入排序的不同之处在于,希尔排序会优先比较距离较远的元素。希尔排序是按照其设计者希尔(DonaldShell)的名字命名而来,并于1959年公布出来。3。希尔排序过程 在介绍完希尔排序之后,我们一起来看一下希尔排序的实现步骤具体是什么样的吧。这里我们假设待排序的序列为〔9,2,11,7,12,5〕,我们按照从小到大的序列进行排序。3。1算法步骤步骤1: 选择一个增量序列k1,k2,km,其中k1k2km1,即增量序列大小依次减小,并且最后一个增量序列大小为1。步骤2: 按照增量序列的个数m,对整个待排序序列进行m趟排序。步骤3: 每一趟排序,根据对应的增量ki,需要将待排序的序列分成对应长度的子序列,分别在子序列上面进行直接插入排序。当且仅当增量序列为1时,整个序列作为一个整体处理。 其实,上面的步骤1和步骤2都是在排序之前进行的处理,选择对应的增量。上面的步骤3每执行一次,就相当于是进行了一次插入排序,只是每次都会选择一个增量,将整个待排序序列按照增量进行划分,然后在对应增量上面进行插入排序。接下来,让我们用上面的待排序数字队列〔9,2,11,7,12,5〕进行整个算法步骤的排序演示工作。3。2算法演示 按照2。1节的排序步骤,我们需要先选择对应的希尔排序中的增量值,按照一般性的原则,我们可以将增量按照待排序的序列长度依次整除2,直到增量为1停止,得到对应的增量。如下:623,321依次获得增量值3,1,除法取整 接着,我们调用2。1中的步骤2,步骤3,按照增量值的取法,依次进行对应序列的插入排序,首先我们取增量值为3,对应排序示例如下:〔9,2,11,7,12,5〕〔9,7〕,〔2,12〕,〔11,5〕增量取3,整个待排序序列按照增量为3进行分组,分成3组,依次排序〔9,7〕,〔2,12〕,〔11,5〕〔7,9〕,〔2,12〕,〔5,11〕对应增量位置进行排序〔7,9〕,〔2,12〕,〔5,11〕〔7,2,5,9,12,11〕完成第一次的对应增量的排序过程 Tips:希尔排序过程中会每次选择一个增量值,然后将待排序列表按照增量值进行分组,对应的分组内部进行插入排序。 在完成增量为3的插入排序之后,我们接着进行增量为1的插入排序,这个步骤其实跟我们之前的插入排序步骤完全一致。整个过程如下:〔7,2,5,9,12,11〕〔7〕;〔2,5,9,12,11〕插入排序初始化,选择第一个元素作为排序好的序列〔7〕;〔2,5,9,12,11〕〔2,7〕;〔5,9,12,11〕选择未排序元素2,插入排序好的序列〔7〕形成新的排序好序列〔2,7〕〔2,7〕;〔5,9,12,11〕〔2,5,7〕;〔9,12,11〕选择未排序元素5,插入排序好的序列〔2,7〕形成新的排序好序列〔2,5,7〕〔2,5,7〕;〔9,12,11〕〔2,5,7,9〕;〔12,11〕选择未排序元素9,插入排序好的序列〔2,5,7〕形成新的排序好序列〔2,5,7,9〕〔2,5,7,9〕;〔12,11〕〔2,5,7,9,12〕;〔11〕选择未排序元素12,插入排序好的序列〔2,5,7,9〕形成新的排序好序列〔2,5,7,9,12〕〔2,5,7,9,12〕;〔11〕〔2,5,7,9,11,12〕选择未排序元素11,插入排序好的序列〔2,5,7,9,12〕形成新的排序好序列〔2,5,7,9,11,12〕 Tips:增量为1时候执行步骤3,实际上就是执行一次插入排序,只是在执行插入排序之前,之前的序列在一定程度上面已经进行了插入排序,所以在增量为1的插入排序过程中可以减少插入时候比较的次数,从而可以在一定程度上面减少算法的运行时间。 从上面的示例可以看出,其实整个希尔排序的过程,就是根据增量大小依次进行插入排序,本质上还是针对插入排序的一种优化。4。Java代码实现 在说明希尔排序的整个过程之后,接下来,我们看看如何用Java代码实现希尔排序算法。importjava。util。Arrays;publicclassShellSort{publicstaticvoidmain(String〔〕args){初始化需要排序的数组intarray〔〕{9,2,11,7,12,5};初始化希尔排序的增量为数组长度intgaparray。length;不断地进行插入排序,直至增量为1while(true){增量每次减半gapgap2;for(inti0;igap;i){内部循环是一个插入排序for(intjigap;jarray。length;jgap){inttemparray〔j〕;intkjgap;while(k0array〔k〕temp){array〔kgap〕array〔k〕;kgap;}array〔kgap〕temp;}}增量为1之后,希尔排序结束,退出循环if(gap1)break;}打印出排序好的序列System。out。println(Arrays。toString(array));}} 运行结果如下:〔2,5,7,9,11,12〕 代码中的第8行初始化一个需要排序的数组,后面按照从小到大的排序规则,实现了数组的排序。第12行至30行是整个希尔排序的流程。第14行代码表示希尔排序中的增量每次整除2取得,第17行至25行是一个for循环结构,表明按照增量进行插入排序。最后第32行代码输出排序好的数组。5。小结 本节主要学习了希尔排序算法,通过本节课程的学习,需要熟悉希尔排序的算法流程,知道希尔排序算法的实现思路,可以自己用代码实现希尔排序算法。至此,我们已经学习了排序算法中的冒泡排序、插入排序、选择排序、希尔排序。