【每日算法】插入排序算法之希尔排序

1)算法简介

希尔排序,也称递减增量排序算法,因DL.Shell于1959年提出而得名,是插入排序的一种高速而稳定的改进版本。

2)算法描述

1、先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。
2、所有距离为d1的倍数的记录放在同一个组中,在各组内进行直接插入排序。
3、取第二个增量d2<d1重复上述的分组和排序,
4、直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

希尔排序的时间复杂度与增量序列的选取有关,例如希尔增量时间复杂度为O(n2),而Hibbard增量的希尔排序的时间复杂度为O(N(5/4)),但是现今仍然没有人能找出希尔排序的精确下界。

3)算法图解、flash演示、视频演示

图解:

希尔排序图解-1
希尔排序图解-2
希尔排序图解-3
希尔排序图解-4

Flash:
http://ds.fzu.edu.cn/fine/resources/FlashContent.asp?id=92

视频:希尔排序Shell Sort 舞蹈
http://v.youku.com/v_show/id_XMjU4NTcwMDIw.html

4)算法代码

#include <stdio.h>
 
int main()
{
     const int n = 5;
     int i, j, temp; 
     int gap = 0;
     int a[] = {5, 4, 3, 2, 1}; 
     while (gap<=n)
     {
          gap = gap * 3 + 1;
     } 
     while (gap > 0) 
     {
         for ( i = gap; i < n; i++ )
         {
             j = i - gap;
             temp = a[i];             
             while (( j >= 0 ) && ( a[j] > temp ))
             {
                 a[j + gap] = a[j];
                 j = j - gap;
             }
             a[j + gap] = temp;
         }
         gap = ( gap - 1 ) / 3;
     }    
 }

5)考察点,重点和频度分析

事实上希尔排序算法在笔试面试中出现的频度也不比直接插入排序高,但它的时间复杂度并不是一个定值,所以偶尔会被面试官问到选择的步长和时间复杂度的关系,要稍微有点了解吧。算法大题中使用该方法或者其思想的题也不多。

6)笔试面试例题

例题1、写出希尔排序算法程序,并说明最坏的情况下需要进行多少次的比较和交换。
程序略,需要O(n^2)次的比较

例题2、设要将序列(Q, H, C, Y, P, A, M, S, R, D, F, X)中的关键码按字母序的升序重新排列,则:

冒泡排序一趟扫描的结果是 H, C, Q, P, A, M, S, R, D, F, X ,Y ;
初始步长为4的希尔(shell)排序一趟的结果是 P, A, C, S, Q, D, F, X , R, H,M, Y ;
二路归并排序一趟扫描的结果是 H, Q, C, Y,A, P, M, S, D, R, F, X ;
快速排序一趟扫描的结果是 F, H, C, D, P, A, M, Q, R, S, Y,X ;
堆排序初始建堆的结果是 A, D, C, R, F, Q, M, S, Y,P, H, X 。

参考

从头说12种排序算法:原理、图解、动画视频演示、代码以及笔试面试题目中的应用

原文地址:https://www.cnblogs.com/shih/p/6618450.html