死磕算法之希尔排序

学习更多算法系列请参考文章:死磕算法之汇总篇

今天讲一下希尔排序,希尔排序呢,其实可以理解为插入算法排序的一个升级版了,不了解插入排序的小伙伴可以先看一下这篇文章:死磕算法之插入排序

我们知道,插入排序在进行排序时如果当数据量很大的时候,有一个很小的数据出现在了数组的最后,那么我们就要移动了这个数据前面所有的元素给它放置到合适的元素。例如:

我们要排序的数组为[1,2,3,4,5,6,7,。。。此处省略一百万。。.,0]。详细大家肯定不喜欢这个0往前移动一百万此吧。

希尔排序的出现其实就是为了解决这个问题的,希尔排序呢,使用了分治算法,先把整个大的数组根据某个增量分为若干个组,先对这若干个组进行一个调整,保证大部分小的数据会被调整到前面来。到最后再次进行插入排序,这样就大大加快了效率了。

来一个例子,我们要排序的数组为[3, 1, 0, 2, 8, 4, 2,6,9,1,3,-2,8],先来看一张图

  1. 上方图片所说的增量就是我们进行分组的依据了。我们在这里初始值取得是数组得2分之一(此值没有标准的定义,只需保证大于1且小于数组长度即可),而红线所指向得就是我们根据这个增量所分的组了,我们分别针对每组进行排序。
  2. 可以在增量为3的结果种看到,第一组3,2,8 变为了2,3,8、第二组第三组没变、第四组变为了1,2、第五组变为了3,8、第六组变为了-2,4.
  3. 接下来增量减半,我们的数组分为3组,分别进行排序。
  4. 现在增量值经过再次减半后已经变为1了,我们可以通过观察数组发现,在数组的后面基本不可能出现最小的数据了,现在对数组进行插入排序的效率已经非常高了。

不知道现在的你明白希尔排序了么?来看一看代码吧。

void shellSort(int list[], int length){
    int gap,i,j,temp;
    for (gap = length/2; gap > 0; gap /= 2)
    {
        for(i = gap; i < length; i++){
            for(j = i-gap; j>=0 && list[j]>list[j+gap]; j -= gap)
            {
                temp = list[j];
                list[j] = list[j+gap];
                list[j+gap] = temp;
            }
        }
     }
}

希尔排序讲完了。在这里温馨提示大家,学习算法时,我们没必要拘泥于代码的实现,那没有意义。我的建议就是深入理解步骤,当你理解步骤以后代码是随你怎么玩都可以的。

原文地址:https://www.cnblogs.com/zhixiang-org-cn/p/9245665.html

时间: 2024-10-13 16:23:14

死磕算法之希尔排序的相关文章

死磕算法之汇总篇

死磕算法之二分查找法 死磕算法之选择排序 死磕算法之插入排序 死磕算法之快速排序 死磕算法之堆排序 死磕算法之希尔排序 死磕算法之冒泡排序 持续更新中............ 原文地址:https://www.cnblogs.com/zhixiang-org-cn/p/9248986.html

死磕算法之堆排序

学习更多算法系列请参考文章:死磕算法之汇总篇 堆排序主要是运用了二叉树的性质来进行的排序. 在进行堆排序之前我们先了解一下二叉树的几个性质: 1.在排序使用二叉树的时候我们要排序的数组的第0个位置其实是不可以用的,这个时候如果我们要排序的数组为[3,1,0,2,8,4,2]时,我们首先要把它变为[0,3,1,0,2,8,4,2],我们把他转换为二叉树的时候是这样的 2.观察此二叉树我们可以发现几个公式: 父节点个数:(数组长度-1)/2 父节点索引为1到父节点个数 子节点的索引:左儿子为父节点索

死磕算法之快速排序

学习更多算法系列请参考文章:死磕算法之汇总篇 快速排序是一个运用了分治法和递归算法的排序方式. 假如我们现在要排序的数组为[3,1,0,2,8,4,2].那么在进行快速排序的时候我们先要进行一些准备: n作为一个数组中的标杆,一趟排序过后我们要把数组中所有大于n的数放在它的右边,所有小于n的放在它的左边.一般情况下我们会取数组第一个元素作为n,在此数组中就是n=3 i我们使用i来找数组中大于标杆的值,i初始指向数组第一个位置 j我们使用j来找数组中小于标杆的值,j初始指向数组最后一个位置 下面开

死磕算法之冒泡排序

学习更多算法系列请参考文章:死磕算法之汇总篇 冒泡排序在排序算法中效率算最慢的一类了,但是因为它简单的缘故仍然是工作1-3年的程序员面试经常会碰到的算法问题,今天就来给大家分析一下冒泡排序的排序流程. 假如我们现在要排序的数组为[3,1,0,2,8,4,2]那么我们第一轮排序为 比较3和1,发现3比1大,那么我们就交换3和1,数组变成了[1,3,0,2,8,4,2] 比较3和0,发现3比0大,那么我们就交换3和0,数组变成了[1,0,3,2,8,4,2] 比较3和2,发现3比2大,那么我们就交换

排序算法之希尔排序

文章转载自http://www.cnblogs.com/chengxiao/ 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一.本文会以图解的方式详细介绍希尔排序的基本思想及其代码实现. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组

【数据结构与算法】希尔排序

希尔排序的时间复杂度是O(n^1.3)~O(n^2),空间复杂度是O(1). 代码如下: /** * 源码名称: ShellSort.java * 日期:2014-08-11 * 程序功能:希尔排序 * 版权:[email protected] * 作者:A2BGeek */ public class ShellSort { public void shellSort(int[] in) { int length = in.length; int span = length / 2; int i

死磕算法之插入排序

学习更多算法系列请参考文章:死磕算法之汇总篇 相信大家都有打扑克的经历,那么我们今天的插入排序就以拿牌为例开始讲(注意只是举例,不是按打牌的规则哦) 1.我们拿到了一张牌3,我们把它放手里,现在手里有牌[3] 2.我们拿到了一张牌1,拿它与手里最后一张牌也就是3比较,发现1比3小,所以我们把它插入到3的前面,现在手里有牌[1,3] 3.我们拿到了一张牌0,拿它与手里最后一张牌也就是3比较,发现0比3小,所以我们把它插入到3的前面,接着与3的上一张比较发现0比1还小,那么就把0在插入到1的前面,现

死磕算法之二分查找法

学习更多算法系列请参考文章:死磕算法之汇总篇 二分查找又称折半算法,此算法作为一个经典的查找算法是我们不得不掌握的算法 这个算法查找的前提是查找的数据是有序的,我们以数组为例,使用二分查找法进行查找的时候我们应该先定义三个字段: 1.left指向数组第一个数据 2.right指向数组最后一个元素 3.mid呢指向(left+right)/2位置的元素,就是他们中间的位置. 当我们要在一个数组中查找一条数据a时,有这么几个步骤: 首先我们拿a与mid比较,如果a与mid相等那么我们就成功找到了这个

算法----(6)希尔排序

希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一 1 def shellSort(nums): 2 # 设定步长 3 step = len(nums)//2 4 while step > 0: 5 for i in range(step, len(nums)): 6 # 类似插入排序, 当前值与指定步长之前的值比较, 符合条件则交换位置