算法系列-直接插入排序和希尔排序

来源:互联网 发布:保险柜哪个品牌 知乎 编辑:程序博客网 时间:2024/06/05 08:43

1、直接插入排序

直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。

设数组为a[0…n-1]。
1)初始时,a[0]自成1个有序区,无序区为a[1..n-1]。令j=1
2)将a[j]并入当前的有序区a[0…j-1]中形成a[0…j]的有序区间。
3)j++并重复第二步直到j==n-1。排序完成。

2、希尔排序

希尔排序的实质就是分组插入排序,该方法又称缩小增量排序。

基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量为1)时,再对全体元素进行一次直接插入排序。

以n=10的一个数组49, 38, 65, 97, 26, 13, 27, 49, 55, 4为例
第一次 gap = 10 / 2 = 5

49   38   65   97   26   13   27   49   55   41A                       1B     2A                       2B          3A                       3B               4A                       4B                    5A                      5B

1A,1B,2A,2B等为分组标记,数字相同的表示在同一组,大写字母表示是该组的第几个元素, 每次对同一组的数据进行直接插入排序。即分成了五组(49, 13) (38, 27) (65, 49) (97, 55) (26, 4)这样每组排序后就变成了(13, 49) (27, 38) (49, 65) (55, 97) (4, 26),下同。

第二次 gap = 5 / 2 = 2

13   27   49   55   4    49   38   65   97   261A        1B       1C         1D        1E     2A        2B        2C        2D        2E

第三次 gap = 2 / 2 = 1

4   26   13   27   38    49   49   55   97   651A  1B   1C   1D   1E    1F   1G   1H   1I   1J

第四次 gap = 1 / 2 = 0

4   13   26   27   38    49   49   55   65   97

从1B开始,先和1A比较,然后取2B与2A比较,再取1C与前面自己组内的数据比较…….。即每次从数组第gap个元素开始,每个元素与自己组内的数据进行直接插入排序。

3、代码

#include <iostream>using namespace std;void print(int a[], int n){    for(int i=0;i<n;i++)        cout<<a[i]<<" ";    cout<<endl;}//直接插入排序void InsertSort(int a[], int n){    int key;//待插入的数    int i;    for(int j=1;j<n;j++)    {//依次将j=1~n-1位置的数插入到前面的有序数组a[0...j-1]        key=a[j];//则a[j]的位置可以空出来,等待其他元素填补        i=j-1;//先跟有序数组最右位置处的数比较,依次向左        while(i>=0 && key<a[i])//key<a[i]时才插入        {            a[i+1]=a[i];//依次将有序数组当前最右位置后移,填补上了原a[j]位置            i=i-1;//向左进行,将key依次跟有序数组元素比较,寻找插入位置        }        a[i+1]=key;//key>a[i],找到插入位置,将key放在a[i+1]处    }}//希尔排序void ShellSort(int a[], int n){    int key;//待插入的数    int i;    for(int gap=n/2;gap>0;gap=gap/2)    {//步长        for(int j=gap;j<n;j++)        {//从每个分组的第二个数开始            key=a[j];            i=j-gap;            while(i>=0 && key<a[i])            {                a[i+gap]=a[i];                i=i-gap;            }            a[i+gap]=key;            //i=i-gap;        }    }}int main(){    int a1[]={6,2,8,3,5,5,20,32,1};    int a2[]={2,8,5,5,6,20,32,1,77,19,2};    //int a3[]={17,5,8,3,88,5,20,32,3};    int n1=sizeof(a1)/sizeof(a1[0]);    int n2=sizeof(a2)/sizeof(a2[0]);    //int n3=sizeof(a3)/sizeof(a3[0]);    InsertSort(a1, n1);    print(a1, n1);    ShellSort(a2, n2);    print(a2, n2);    return 0;}
0 0
原创粉丝点击