zoukankan      html  css  js  c++  java
  • 希尔排序

    【1】希尔排序

    严格而言,希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。

    该方法又称缩小增量(逐渐缩小排序元素相隔差距)排序。

    希尔排序是不稳定排序算法(参见随笔《常用排序算法稳定性分析》)。

    【2】希尔排序逻辑

    希尔排序逻辑分析:

    (1)先取一个小于N的整数d1作为第一个增量,把待排序的全部记录分成d1个组。所有距离相隔为d1(或距离为d1的倍数)记录放在同一个组中。

    怎么理解这个规则?即就是:如果N == 16 ,d1 == 4,那么按照索引(index)分组为:

    <1> 0,4,8,12为一组;

    <2> 1,5,9,13为一组;

    <3> 2,6,10,14为一组;

    <4> 3,7,11,15为一组。

    (2)先在各组内进行直接插入排序;

    (3)取第二个增量d2 < d1重复上述的分组和排序。

    (4)重复(1),(2),(3)直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

    【3】希尔排序动态演示

    假设待排序序列有10个记录,其关键数据分别为:

    49,38,65,97,76,13,27,49,55,04

    增量序列的取值依次为:

    5,3,1

    那么,排序过程【动画模拟演示

    【4】C++实现希尔排序

    (1)实现并测试程序

      1 #include<iostream>
      2 using namespace std;
      3 
      4 #define   MAXSIZE  10
      5  
      6 int nCnt = 0;   //统计排序趟数
      7 
      8 //打印排序结果
      9 void  PrintArr(int ar[],int n)
     10 {
     11     for(int i = 0; i < n; ++i)
     12         cout<<ar[i]<<" ";
     13     cout<<endl;
     14 }
     15 
     16 void ShellSort(int ar[], int begin, int end)  
     17 {  
     18     int gap = end-begin+1;    //gap初始值
     19     cout<<"gap = "<<gap<<endl;
     20     while(gap > 1)  
     21     {  
     22         ++nCnt;
     23         gap = gap/3 + 1;    //当趟排序gap值确定
     24         cout<<"gap = "<<gap<<endl;
     25         for(int i = begin + gap; i < end; ++i)  
     26         {  
     27             cout<<"i = "<<i<<endl;
     28             int temp = ar[i];    //暂存关键数据
     29             cout<<"temp = "<<temp<<endl;
     30             int j = i;  
     31             while(j-gap >= begin && temp < ar[j-gap])  
     32             {  
     33                 ar[j] = ar[j-gap];   //后移
     34                 j = j-gap;     //前置索引
     35             }  
     36             cout<<"j = "<<j<<endl;
     37             ar[j] = temp;   //插入关键数据
     38         } 
     39         cout<<""<<nCnt<<"趟排序gap = "<<gap<<"结果如下:"<<endl;
     40         PrintArr(ar, MAXSIZE);
     41     }  
     42 } 
     43 
     44 void  main()
     45 {
     46     int  ar[MAXSIZE] = {56, 38, 65, 97, 76, 13, 27, 49, 55, 04};
     47     ShellSort(ar,0,MAXSIZE);
     48 }
     49 
     50 /*
     51 gap = 11
     52 gap = 4
     53 i = 4
     54 temp = 76
     55 j = 4
     56 i = 5
     57 temp = 13
     58 j = 1
     59 i = 6
     60 temp = 27
     61 j = 2
     62 i = 7
     63 temp = 49
     64 j = 3
     65 i = 8
     66 temp = 55
     67 j = 0
     68 i = 9
     69 temp = 4
     70 j = 1
     71 第1趟排序gap = 4结果如下:
     72 55 4 27 49 56 13 65 97 76 38
     73 gap = 2
     74 i = 2
     75 temp = 27
     76 j = 0
     77 i = 3
     78 temp = 49
     79 j = 3
     80 i = 4
     81 temp = 56
     82 j = 4
     83 i = 5
     84 temp = 13
     85 j = 3
     86 i = 6
     87 temp = 65
     88 j = 6
     89 i = 7
     90 temp = 97
     91 j = 7
     92 i = 8
     93 temp = 76
     94 j = 8
     95 i = 9
     96 temp = 38
     97 j = 5
     98 第2趟排序gap = 2结果如下:
     99 27 4 55 13 56 38 65 49 76 97
    100 gap = 1
    101 i = 1
    102 temp = 4
    103 j = 0
    104 i = 2
    105 temp = 55
    106 j = 2
    107 i = 3
    108 temp = 13
    109 j = 1
    110 i = 4
    111 temp = 56
    112 j = 4
    113 i = 5
    114 temp = 38
    115 j = 3
    116 i = 6
    117 temp = 65
    118 j = 6
    119 i = 7
    120 temp = 49
    121 j = 4
    122 i = 8
    123 temp = 76
    124 j = 8
    125 i = 9
    126 temp = 97
    127 j = 9
    128 第3趟排序gap = 1结果如下:
    129 4 13 27 38 49 55 56 65 76 97
    130 
    131  */

    (2)希尔排序实现代码

     1 void ShellSort(int ar[], int begin, int end)  
     2 {  
     3     int gap = end-begin+1;    //gap初始值大于0
     4     while(gap > 1)  
     5     {  
     6         gap = gap/3 + 1;    //当趟排序gap值确定
     7         for(int i = begin + gap; i < end; ++i)  
     8         {  
     9             int temp = ar[i];    //暂存关键数据
    10             int j = i;  
    11             while(j-gap >= begin && temp < ar[j-gap])  
    12             {  
    13                 ar[j] = ar[j-gap];   //后移
    14                 j = j-gap;     //前置索引
    15             }  
    16             ar[j] = temp;   //插入关键数据
    17         } 
    18     }  
    19 } 

     

    Good Good Study, Day Day Up.

    顺序  选择  循环  坚持  总结

    作者:kaizen
    声明:本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此声明,且在文章明显位置给出本文链接,否则保留追究法律责任的权利。
    签名:顺序 选择 循环
  • 相关阅读:
    linux学习(三)输入输出重定向和管道功能、cat命令、more命令
    linux基础学习(二)ls命令以及文件访问权限例(-rw-r-r--)
    c语言的全排列
    linux基础学习(一)常用命令:date、pwd、cd、cal、who、wc等等
    用linux编译并运行c文件
    安装linux虚拟机
    安装quickLook插件以及解决如何不能读取offic问题
    java:数据结构(四)二叉查找树以及树的三种遍历
    java:数据结构复习(三)链表队列
    数据结构java学习(三)循环队列
  • 原文地址:https://www.cnblogs.com/Braveliu/p/2859399.html
Copyright © 2011-2022 走看看