希尔排序--ShellSort()

一、ShellSort--希尔排序 

本质上:希尔排序是gap>1时的预排序  +  gap==1时的插入排序

特点:gap越大,大的数越快到后面,小的数越快到前面,越接近无序; gap越小,大的数越慢到后面,小的数越慢到前面,越接近有序。

在这里插入图片描述

1.思路 

(1).第一步--预排序(接近有序)
(2).第二步--直接插入排序(有序)

2.实现 

void ShellSort(int* a, int n)//针对数据量大的
{


    一、单趟的插入
  

    int gap = 3;

//1.第一个for是表示第几组
    for (int j = 0; j < gap; ++j)为啥j<gap,因为gap是个组
                                   距,全部数是被分为gap组的,
                                   同组中的数间隔gap.包括间隔
                                   中的数和本身,就只有gap个
    {

//2.第二个for表示第j组中的第几个
        for (int i = j; i < n - gap; i += gap)
        {
            int end = i;
            int tmp = a[end + gap];
            while (end >= 0)
            {
                if (tmp < a[end])
                {
                    a[end + gap] = a[end];
                    end -= gap;
                }
                else
                {
                    break;
                }
            }
            a[end + gap] = tmp;
        }
    }


    
            
二、多趟的插入


1.法1        将每一组gap分开完成,先完成一组再完成另一组
    //多趟的插入
    // gap > 1时是预排序
    // gap 最后一次等于1,是直接插入排序

    int gap = n;
    while (gap > 1)
    {
        gap = gap / 3 + 1;//官方规定的gap的缩减速度,当gap缩减到1时,则变为了插入排序
        for (int j = 0; j < gap; ++j)//先完成一个的,再完成另一个
        {                          为啥j<gap,因为gap是个组
                                   距,全部数是被分为gap组的,
                                   同组中的数间隔gap.包括间隔
                                   中的数和本身,就只有gap个
        
            for (int i = j; i < n - gap; i += gap)//为啥i<n-gap,因为下面要满足i+gap<n
            {
                int end = i;
                int tmp = a[end + gap];
                while (end >= 0)
                {
                    if (tmp < a[end])
                    {
                        a[end + gap] = a[end];
                        end -= gap;
                    }
                    else
                    {
                        break;
                    }
                }
                a[end + gap] = tmp;
            }
        }
    }

疑问:

1.for (int j = 0; j < gap; ++j)      为啥j<gap,因为gap是个组距,全部数是被分为gap组的,同组中的数间隔gap.包括间隔中的数和本身,就只有gap个

2.for (int i = j; i < n - gap; i += gap)//为啥i<n-gap,因为下面要满足i+gap<n ,

如int tmp = a[end + gap];
         

2.法2        所有gap组并发进行

    //多趟的插入
    // gap > 1时是预排序
    // gap 最后一次等于1,是直接插入排序

    
 

   int gap = n;
    while (gap > 1)
    {
        gap = gap / 3 + 1;

        for (int i = 0; i < n - gap; ++i)//gap组数据交替插入排序(优化)
        {
            int end = i;
            int tmp = a[end + gap];
            while (end >= 0)
            {
                if (tmp < a[end])
                {
                    a[end + gap] = a[end];
                    end -= gap;
                }
                else
                {
                    break;
                }
            }
            a[end + gap] = tmp;
        }
    }

}
图解:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值