看图说话排序算法之希尔排序
2017-11-02 17:38
197 查看
排序算法之希尔排序
希尔排序是最早突破O(n2)时间界限的一种排序算法,希尔排序算法是在插入排序算法的基础上进行改进的排序算法,上文描述了插入排序的基本实现过程,本文在上文基础上介绍希尔排序的基本原理。
一丶希尔排序算法基本原理
希尔排序又称为增量排序,该算法依据增量将待排序数组划分成不同子数组,并对每个子数组运用插入排序,最后对各个排序后的子数组进行一次插入排序,从而完成排序操作。希尔排序算法的实现流程如图所示:
![](https://img-blog.csdn.net/20171102174340314?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzAzMjI4MDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图1 算法实现流程
下面通过一个例子,来描述希尔排序算法的具体实现过程,假设待排序数组满足int [] A = new int[]{4,5,7,3,2,8,9,16,13}。
(1)数组长度N=9,所以初始增量delta = N/2 = 4,依据增量delta可以将数组划分成如下子数组(长度为1的子数组不画,没有排序的必要)
![](https://img-blog.csdn.net/20171102174400797?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzAzMjI4MDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图2 delta=4时子数组划分情况
(2)依据增量划分子数组之后,对每个子数组进行直接插入排序,排序结果如下图所示:
![](https://img-blog.csdn.net/20171102174416556?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzAzMjI4MDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图3 delta=4时子数组排序情况
从上图可以看到,对各个子数组进行插入排序,实质上也是对待排序数组一次顺序调整。
(3)经过上述两步之后,待排序数组由{4,5,7,3,2,8,9,16,13}调整到了{2,5,7,3,4,8,9,16,13}的顺序,接着对数组{2,5,7,3,4,8,9,16,13}重复上述两个步骤,此时增量delta =delta/2=2。划分子数组和排序情况分别如下图所示
![](https://img-blog.csdn.net/20171102174436322?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzAzMjI4MDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图4 delta=2时子数组划分情况
![](https://img-blog.csdn.net/20171102174500824?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzAzMjI4MDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图5delta=2时子数组排序情况
结合步骤(1)和步骤(2)的描述,对比图3,图4的变化,不难看出该次排序的过程。随着增量delta的减小,子数组的数量越多,对上述过程细心的话,可以看出,假如不经过增量delta=4的排序过程,直接进入delta=2的排序过程,各个子数组需要调整的元素会增多,从这个角度来看delta=4的增量排序是为了delta=2的增量排序做铺垫。
(4)经过步骤(3)待排序数组由{2,5,7,3,4,8,9,16,13}的顺序调整至{2,3,4,5,7,8,9,16,13}。此时delta = delta/2 = 1。重复步骤(1)和步骤(2),由于次数delta=1,相当于对整个数组进行一次插入排序,排序结果如下图所表示。
![](https://img-blog.csdn.net/20171102174522761?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzAzMjI4MDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图6delta=1时排序情况
观察图5中的待排序数组,不难发现经过增量delta=4,和delta=2的排序后,待排序数组已经基本有序了。由于插入排序在基本有序的前提下,时间消耗接近线性,所以这趟排序所用时间消耗比较小,可以说前面的所有的增量排序,都是为了优化最后这一次插入排序。
总结:
(1)通过上述所有步骤的描述,对希尔排序算法的时间过了有了一个清晰认识,但是感觉对希尔排序的时间复杂度分析无从下手,没有插入排序那么直观。事实上希尔排序的时间复杂度分析是一件困难的事情。
(2)我的自身水平也有限,我也没有能力证明希尔排序的时间复杂度。只能描述希尔排序算法的一般实现过程
(3)可以推断希尔排序的效率依赖于delta增量,delta增量选取合适的话,可以优化不小的效率,对delta增量计算的方式有很多种,对此不做深入介绍,本文中描述的delta增量计算的方式称为希尔增量计算法。
(4)希尔排序算法优于时间复杂度是O(n2)的算法,但没有达到nlog(n)的时间界,希尔排序算法在适度规模的数据下排序具有较优的性能,比较常用。
二丶java代码实现
public class ShellSort {
public static void main(String [] args){
int [] data = new int[]{5,4,6,2,9,1,7};
shellSort(data);
for(int i =0;i<data.length;i++){
System.out.println(data[i]);
}
}
public static void shellSort(int [] data){
//shell 排序的增量循环
for(int delta=data.length/2;delta>0;delta=delta/2){
for(int i=0;i<data.length-delta;i++){
int temp =data[delta+i];
int index =delta+i;
while(index-delta>=0&&data[index-delta]>temp){
data[index]=data[index-delta];
index=index-delta;
}
data[index] =temp;
}
}
}
}
希尔排序是最早突破O(n2)时间界限的一种排序算法,希尔排序算法是在插入排序算法的基础上进行改进的排序算法,上文描述了插入排序的基本实现过程,本文在上文基础上介绍希尔排序的基本原理。
一丶希尔排序算法基本原理
希尔排序又称为增量排序,该算法依据增量将待排序数组划分成不同子数组,并对每个子数组运用插入排序,最后对各个排序后的子数组进行一次插入排序,从而完成排序操作。希尔排序算法的实现流程如图所示:
图1 算法实现流程
下面通过一个例子,来描述希尔排序算法的具体实现过程,假设待排序数组满足int [] A = new int[]{4,5,7,3,2,8,9,16,13}。
(1)数组长度N=9,所以初始增量delta = N/2 = 4,依据增量delta可以将数组划分成如下子数组(长度为1的子数组不画,没有排序的必要)
图2 delta=4时子数组划分情况
(2)依据增量划分子数组之后,对每个子数组进行直接插入排序,排序结果如下图所示:
图3 delta=4时子数组排序情况
从上图可以看到,对各个子数组进行插入排序,实质上也是对待排序数组一次顺序调整。
(3)经过上述两步之后,待排序数组由{4,5,7,3,2,8,9,16,13}调整到了{2,5,7,3,4,8,9,16,13}的顺序,接着对数组{2,5,7,3,4,8,9,16,13}重复上述两个步骤,此时增量delta =delta/2=2。划分子数组和排序情况分别如下图所示
图4 delta=2时子数组划分情况
图5delta=2时子数组排序情况
结合步骤(1)和步骤(2)的描述,对比图3,图4的变化,不难看出该次排序的过程。随着增量delta的减小,子数组的数量越多,对上述过程细心的话,可以看出,假如不经过增量delta=4的排序过程,直接进入delta=2的排序过程,各个子数组需要调整的元素会增多,从这个角度来看delta=4的增量排序是为了delta=2的增量排序做铺垫。
(4)经过步骤(3)待排序数组由{2,5,7,3,4,8,9,16,13}的顺序调整至{2,3,4,5,7,8,9,16,13}。此时delta = delta/2 = 1。重复步骤(1)和步骤(2),由于次数delta=1,相当于对整个数组进行一次插入排序,排序结果如下图所表示。
图6delta=1时排序情况
观察图5中的待排序数组,不难发现经过增量delta=4,和delta=2的排序后,待排序数组已经基本有序了。由于插入排序在基本有序的前提下,时间消耗接近线性,所以这趟排序所用时间消耗比较小,可以说前面的所有的增量排序,都是为了优化最后这一次插入排序。
总结:
(1)通过上述所有步骤的描述,对希尔排序算法的时间过了有了一个清晰认识,但是感觉对希尔排序的时间复杂度分析无从下手,没有插入排序那么直观。事实上希尔排序的时间复杂度分析是一件困难的事情。
(2)我的自身水平也有限,我也没有能力证明希尔排序的时间复杂度。只能描述希尔排序算法的一般实现过程
(3)可以推断希尔排序的效率依赖于delta增量,delta增量选取合适的话,可以优化不小的效率,对delta增量计算的方式有很多种,对此不做深入介绍,本文中描述的delta增量计算的方式称为希尔增量计算法。
(4)希尔排序算法优于时间复杂度是O(n2)的算法,但没有达到nlog(n)的时间界,希尔排序算法在适度规模的数据下排序具有较优的性能,比较常用。
二丶java代码实现
public class ShellSort {
public static void main(String [] args){
int [] data = new int[]{5,4,6,2,9,1,7};
shellSort(data);
for(int i =0;i<data.length;i++){
System.out.println(data[i]);
}
}
public static void shellSort(int [] data){
//shell 排序的增量循环
for(int delta=data.length/2;delta>0;delta=delta/2){
for(int i=0;i<data.length-delta;i++){
int temp =data[delta+i];
int index =delta+i;
while(index-delta>=0&&data[index-delta]>temp){
data[index]=data[index-delta];
index=index-delta;
}
data[index] =temp;
}
}
}
}
相关文章推荐
- 看图说话排序算法之冒泡排序
- 看图说话排序算法之快速排序
- 看图说话排序算法之归并排序
- 看图说话排序算法之插入排序
- 排序算法-希尔排序 Shell Sort
- 排序算法-希尔排序
- 排序算法(二)、插入排序 —— 直接插入排序 和 希尔排序
- 初级排序算法(选择排序、插入排序、希尔排序)
- 【排序算法】:希尔排序
- 排序算法(希尔排序)
- 各种排序算法的实现-6(希尔排序的实现)
- 数据结构6-排序算法(直接插入排序、希尔排序、快速排序、归并排序和堆排序)
- 看图不说话
- 练打字-测试看图说话(AD安装)
- 看图说话:你不了解的OA与SAP集成
- 排序算法(四) —— 希尔排序
- 深入浅出理解排序算法之-希尔排序
- 数据结构-排序算法详解(插入排序,希尔排序,堆排序,归并排序,快速排序,桶式排序)
- 笔试面试最常涉及到的12种排序算法(包括插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序、桶排序、计数排序和基数排序)进行了详解。每一种算法都有基本介绍、算
- 看图说话:11种用户,你如何应对?