C#学习笔记本--第二篇(排序算法之希尔排序,插入排序Plus)

一、基本原理:

         希尔排序是插入排序的升级版  必须先得掌握插入排序

        希尔排序的原理:
将整个待排序序列分成多个子序列,每个子序列的元素个数逐渐增加 分别进行插入排序

        总而言之
       希尔排序对插入排序的升级主要就是加入了一个步长的概念 ,通过步长每次可以把原序列分为多个子序列,然后对子序列进行插入排序,在极限情况下可以有效降低普通插入排序的时间复杂度,提高算法效率

二、图形化解释

步长步长就是一步之长,步长就是数组长度除以2的取值。插入排序的步长可以看成一,然后进行排序

        将步长所在位置的元素看成是待排序区,往前一个步长就是他的已排序区,这里就可以看成是前面插入排序的时候的两个区域。每次将小区域里面的元素排序完成后,就将索引往后移动,将新的小区域继续比较,如此反复,直到索引超过数组长度,一轮排序结束。

        第二轮排序和第一轮原理相同,先把步长在再次除以2,获得新的步长,然后将新的一个个小区域中的元素进行比较,直到比较结束,该轮比较结束。可以看到已经很有序了。

第三轮开始时,步长就是一了,就和前面写的插入排序是一样的了

小结:希尔排序在极端条件下会节省时间复杂度,提高代码效率

三、代码实现

①由于他是插入算法的升级版,肯定和插入算法脱不了关系,先写一个插入算法

int[] arr = new int [9]{ 8, 7, 1, 5, 4, 2, 6, 3, 9 };

for (int i = 1; i < arr.Length; i++)
 { 
   int unSortValue = arr[i];//得出未排序区的元素
   int sortIndex = i - 1;//得到排序区最后一个元素索引
   while (sortIndex >= 0 && arr[sortIndex] > unSortValue)
     {
      arr[sortIndex+1] = arr[sortIndex];//元素后移
       sortIndex--;
    }
   arr[sortIndex + 1] = unSortValue;//插入元素
 
}

②步长怎么获取呢,由于第一次是数组长度的一般,后面都是/2很容易想到for循环

for(int step = arr.Lenth/2;step>0;step/=2)
{
}

③由于每一轮排序都是在反复使用插入排序,自然而然想到将,前面插入排序的代码直接镶嵌进去即可,只需要对其中的1改为步长即可

for (int step = arr.Length / 2; step > 0; step /= 2)
{
    //i = 1 相当于 代表取出来的排序区的第一个元素
    //for (int i = 1; i < arr.Length; i++)
    //i = step 相当于代表取出来的排序区的第一个元素
    for (int i = step; i < arr.Length; i++)
    {
        int unSortValue = arr[i];//得出未排序区的元素
        //int sortIndex = i - 1;//得到排序区最后一个元素索引
        
        int sortIndex = i - step;//代表和子序列中 已排序区的元素一一比较
        while (sortIndex >= 0 && arr[sortIndex] > unSortValue)
        {
            //arr[sortIndex + 1] = arr[sortIndex];//元素后移
            arr[sortIndex + step] = arr[sortIndex];//代表移步长个位置 代表子序列中的下一个位置
            //sortIndex--;
            sortIndex -= step;//代表子序列中的下一个位置
        }
        //arr[sortIndex + 1] = unSortValue;//插入元素
        arr[sortIndex + step] = unSortValue;//找到真正的位置然后插入

    }
    

}

到这里代码就实现了

四、总结

套路写法
三层循环
一层获取步长
一层获取未排序区的元素
一层找到合适位置插入

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值