`
aladdin_leon
  • 浏览: 118485 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

排序的故事--SHELL排序

阅读更多

     SHELL是一种不需要辅助空间不稳定的排序法,在传统的教科书里面,SHELL排序法都是直接引用D.L.Shell在他1969年的原著《A High-Speed Sorting Procedure》中的办法:再要排序的数组中先把间隔为n/2的元素排好,然后把间隔为n/(2^2)的元素排好,再排间隔为n/(2^3),n/(2^4),... ,4,2,1的元素,最后就是一个依顺序排序好的结果。C程序如下:

  1. void sort(int x[], int n)   
  2. {   
  3.        int gap;   
  4.        int i, j, temp;   
  5.        while(gap>0)      
  6.        {   
  7.             for (i=gap; i
  8.                 for (j=i-gap; j>=0 && x[j]>x[j+gap]; j-= gap) {   
  9.                      temp = x[j];   
  10.                      x[j] = x[j+gap];   
  11.                      x[j+gap] = temp;   
  12.                 }   
  13.                 gap = gap/2;       
  14.        }   
  15. }          

      但是D.Kunth的著作中把早期的研究与他的发现作了一个总结,他指出用(2^j)-1,(2^j)-1的间隔进行排序分别是Hibbard、Papernovn与Stasevich的想法,而间隔数((3^j)-1)/2则是在他的书中首度出现的,把比较次数加快到与n^1.5成正比。
      D.Knuth很早就发现如何用((3^j)-1)/2的方式,亦即1,4,13,... ,这样的方法会比Shell原来的方法好一些。换言之,如果有n个元素,就得找出满足((3^j)-1)/2       后来就是青出于蓝而胜于蓝的故事,他的一名学生Robert Sedgewick把间隔数定为:4^(j+1)+3*(2^j)+1,于是把比较次数加快到了与n^(4/3)成正比,虽然1.5只比1.33多不了多少,但是这种科学家的精神我还是很佩服的。当然了还有好多关于间隔数如何选取的方法,这里就不一一介绍了。下面我们就以Robert Sedgewick的算法为例进行研究...
      由于4^(j+1)+3*(2^j)+1是需要排序的元素之间的间隔,因此它不能大于所有的元素的个数n,所以j必须满足下式:
               4^(j+1)+3*(2^j)+1 <= n
      把 4^(j+1)改写为4*(4^j)=4*[(2^j)]^2带回上式,就有:
               4*[(2^j)]^2 + 3*(2^j) + (1-n) <= 0
      把2^j用X换掉,于是就有:
               4*(X^2) + 3*X + (1-n) <= 0
      通过解方程和函数的特性(开口向上的抛物线)于是就可以求出j的最大值为:log[(-3+(16n-7)^1/2)/8]
      在程序中,可以用上面求出的j算出一个2^j,代入 4*[(2^j)]^2 + 3*(2^j) + 1,以求出的间隔值进行排序接着把2^j除以2,在代入4*[(2^j)]^2 + 3*(2^j) + 1得到一个新间隔值进行排序...一直到间隔为1时元素就排好顺序了,整个排序就大功告成了!

  1. #include  <math.h></math.h>             
  2. #include  <stdio.h></stdio.h>   
  3. #include  <stdlib.h></stdlib.h>   
  4. #define   EQN(x) ((4*x+3)*x+1)   
  5.   
  6. void  sort(int x[], int n)   
  7. {   
  8.        int  gap;                   
  9.        int  power2;                
  10.        int  i, j, temp;            
  11.        power2 = log((-3.0 + sqrt(16.0*n-7.0))/8.0)/log(2.0);   
  12.        power2 = 1 << (power2 + 1);   
  13.        do  
  14.        {   
  15.              power2 >>= 1;   
  16.              gap = EQN(power2);   
  17.              for (i = gap; i < n; i++)   
  18.                   for (j=i-gap; j>=0 && x[j] > x[j+gap]; j -= gap)    
  19.                   {   
  20.                        temp = x[j];   
  21.                        x[j] = x[j+gap];   
  22.                        x[j+gap] = temp;   
  23.                   }   
  24.         } while (gap > 1);   
  25. }  

      好了让我们测试一下这个算法吧,main函数根据根据输入参数随机生成input数组,然后把input传给sort函数进行排序,然后输出结果,测试程序如下:

  1. #include  <time.h></time.h>   
  2. #define   MAXSIZE   1000   
  3.          
  4. int main(void)   
  5. {   
  6.       int input[MAXSIZE+1];   
  7.       int  n, i;   
  8.       char line[100];   
  9.   
  10.       printf("\nSort Program Testing Driver for Random Data");   
  11.       printf("\n-------------------------------------------");   
  12.       printf("\n number of the item"); 
  13.       gets(line);   
  14.       n = atoi(line);   
  15.       srand((unsigned)clock());   
  16.       printf("\nGenerated Data :");   
  17.       for(i = 0; i < n; i++)   
  18.       {   
  19.             if (i % 10 == 0)  printf("\n");   
  20.             input[i] = rand();   
  21.             printf("%6d", input[i]);   
  22.       }   
  23.       sort(input, n);   
  24.       printf("\n\nSorted Data :");   
  25.       for (i = 0; i < n; i++)    
  26.       {   
  27.             if (i % 10 == 0)  printf("\n");   
  28.             printf("%6d", input[i]);   
  29.       }   
  30.       getchar();   
  31. }  


      

分享到:
评论

相关推荐

    基于Python实现的K-Shell节点排序算法

    基于python-2.7实现的K-Shell节点排序算法,算法结果输出每个节点K值。

    C经典算法之Shell 排序法 - 改良的插入排序

    ### C经典算法之Shell排序法 - 改良的插入排序 #### 描述 在计算机科学领域,排序算法一直是研究的重点之一。插入排序是一种简单的排序方法,其基本思想是从待排序序列中依次取出元素与已排序的部分进行比较并插入...

    基于python的排序算法-希尔排序Shell Sort

    希尔排序(Shell Sort)是一种插入排序的改进版,由Donald Shell在1959年提出。它是通过将待排序的数据序列划分为多个子序列,然后对每个子序列进行插入排序,逐渐减少子序列的间隔,直到间隔为1,即整个序列成为一...

    经典算法的C#源码实现

    经典排序算法 - 希尔排序Shell sort 经典排序算法 - 堆排序Heap sort序 经典排序算法 - 地精排序Gnome Sort 经典排序算法 - 奇偶排序Odd-even sort 经典排序算法 - 梳排序Comb sort 经典排序算法 - 耐心排序...

    直接插入排序、折半排序、shell排序、冒泡排序、快速排序、选择排序、堆排序的实现

    数据结构(c语言版)严蔚敏 吴伟民编著 中直接插入排序、折半排序、shell排序、冒泡排序、快速排序、选择排序、堆排序的实现、归并排序,使用c语言实现

    shell排序shellsort

    数据结构课程排序算法中的经典shell排序

    排序算法-基于C语言实现的排序算法之ShellSort实现.zip

    ShellSort,又称希尔排序,是由美国计算机科学家Donald Shell于1959年提出的一种改进的插入排序算法。它通过将待排序的元素按照一定的间隔分组,然后对每组进行插入排序,随着间隔逐渐减小,最终达到整体有序。这种...

    多线程排序---希尔排序、快速排序、堆排序

    希尔排序是一种基于插入排序的算法,由Donald Shell于1959年提出。它的核心思想是将待排序的数据按照一定的间隔(称为增量)分组,对每组进行插入排序,然后逐渐减小增量,直至增量为1,最终完成整个序列的排序。...

    java实现的shell排序快速排序归并排序堆排序

    本篇将详细介绍标题所提及的四种排序算法:Shell排序、快速排序、归并排序以及堆排序。 1. **Shell排序**: Shell排序是一种改进的插入排序,由Donald Shell于1959年提出。它通过设置一个间隔序列,使得数组中的...

    三种排序-SHELL,快速,堆

    这里我们关注的是三种常见的排序算法:希尔排序(Shell Sort)、快速排序(Quick Sort)和堆排序(Heap Sort)。这些算法各有特点,适用于不同的场景,理解和掌握它们对于提升编程能力非常有帮助。 首先,希尔排序...

    C语言版的排序方法---希尔排序.docx

    希尔排序是一种基于插入排序的快速排序算法,由Donald Shell在1959年提出。它的主要特点是通过将待排序的序列分成若干个子序列来减少元素之间的比较次数,从而提高排序效率。希尔排序的核心思想是“增量序列”,即在...

    排序算法--免费

    4. **希尔排序(Shell Sort)** - 希尔排序是插入排序的改进版,通过间隔序列(希尔增量)分组进行排序,逐步减小间隔,直至为1,从而提高效率。 - 在C++中,希尔排序需要定义一个增量序列,然后对每个子序列进行...

    C 冒泡Shell排序算法

    总结,C语言实现冒泡Shell排序算法是将冒泡排序与Shell排序结合,先用Shell排序优化初步排序,再用冒泡排序进行微调,以达到更好的性能。理解并掌握这些基础排序算法有助于我们更好地理解和设计更复杂的排序算法。在...

    C++的Shell排序算法代码学习

    ### C++中的Shell排序算法详解 #### 一、Shell排序简介 Shell排序是插入排序的一种扩展,由Donald Shell于1959年提出。它通过将原始数组分割成多个子序列,分别对这些子序列进行插入排序来提高插入排序的效率。随着...

    简单数据排序--JavaScrip实现

    function ShellSort(arr) { //插入排序-&gt;希儿排序 var st = new Date(); var increment = arr.length; do { increment = (increment/3|0) + 1; arr = ShellPass(arr, increment); } while (increment &gt; 1) ...

    数据结构排序知识--很有用啊

    2. 希尔排序(Shell Sort): 希尔排序是一种改进的插入排序,通过设置间隔(gap)来分组元素,然后对每个组进行插入排序。间隔会逐渐减小,直到为1,这时再进行一次插入排序。在这个实现中,`shellsort` 函数使用了...

    希尔排序 又称shell排序

    ### 希尔排序(Shell Sort)详解 #### 一、引言 希尔排序是一种基于插入排序的高效排序算法,由计算机科学家Donald Shell在1959年提出。该算法通过将原始序列分割成多个子序列,分别进行插入排序来提高排序效率。...

    实现各种排序算法并分析与比较.rar_shell排序_各种排序_各种排序算法_堆排序_快速排序

    本文将深入探讨标题和描述中提及的几种排序算法:直接插入排序、希尔排序(SHELL排序)、冒泡排序、快速排序、简单选择排序、堆排序以及归并排序,并对它们进行分析和比较。 1. **直接插入排序**: - 直接插入排序...

    常见排序算法-C语言

    C语言实现常见排序算法。编译环境:VS2010。 包括: 冒泡排序 ...Shell排序 直接选择排序 堆排序 归并排序(递归和非递归两种) 桶式排序 基数排序:顺序和静态队列两种方法 索引排序(采用简单插入排序)

Global site tag (gtag.js) - Google Analytics