希尔排序算法小记(javascript代码实现)

前言

今天做排序的时候,把希尔排序写错了。写一篇希尔排序原理惩罚自己。

1 原理概述

希尔排序是插入排序的一种改进算法。它先将一个大的待排序数列分成多个小的分组,并分别对这些小的分组使用插入排序算法。经过多轮分组与组内排序,逐步合并小的分组,最终将分组重新合并成一个有序序列。

那么怎么将一开始分出的这些小分组合并成一个完整的数列呢?规则是什么呢?客官请往下看。

2 算法描述

由于个人描述能力欠佳,为避免说的太抽象,这里我们结合实例进行介绍。

这里有一个需要进行排序的数列 arr = [88, 10, 47, 41, 39, 15, 0, 53, 6, 75],下面我们要对它执行希尔排序。

希尔排序在对数列进行分组时,用到一个概念,我们之为“增量”。增量即为分组的步长。这里使用的是希尔增量

希尔排序开始前,按照实际需要设定一个初始增量(我们这里设定 fraction = arr.length / 2,即增量为 5)。这样就可以将数列分组,并对每个分组执行插入排序。所有分组都执行完插入排序,视为第一轮排序完成。

让我们看看这一轮排序发生了什么:

// 排序前
[88, 10, 47, 41, 39, 15, 0, 53, 6, 75]
 88 ***************** 15
 **** 10 ***************** 0
 ******** 47 *************** 53
 ************* 41 *************** 6
 **************** 39 ************** 75

// 排序后
[15, 0, 47, 6, 39, 88, 10, 53, 41, 75]
 15 ************** 88
 **** 0 **************** 10
 ******** 47 **************** 53
 ********** 6 **************** 41
 ************* 39 ***************** 75

在第1轮排序中,数列被分为5个分组,经过本轮排序,此时每个分组内部均为有序。

此时,将增量减小(fraction = 5 / 2,即步长为 2),重新划分数列,并对每个新的分组执行插入排序。

我们看一下这一轮排序发生了什么:

// 排序前
[88, 10, 47, 41, 39, 15, 0, 53, 6, 75]
 88 **** 47 **** 39 ***** 0 **** 6
 *** 10 **** 41 ***** 15 *** 53 *** 75

// 排序后
[0, 10, 6, 15, 39, 41, 47, 53, 88, 75]
 0  **** 6 **** 39 **** 47 **** 88
 ** 10 *** 15 **** 41 **** 53 **** 75

在第2轮排序中,数列被分为2个分组,经过本轮排序,此时每个分组内部均为有序。

此时,再次减小增量(fraction = 2 / 2 ,即步长为1),重新划分数列,并对每个新的分组执行插入排序。
我们看一下这一轮排序发生了什么:

// 排序前
[0, 10, 6, 15, 39, 41, 47, 53, 88, 75]

// 排序后
[0, 6, 10, 15, 39, 41, 47, 53, 75, 88]

在第3轮排序中,数列只有一个分组,经过本轮排序,整个数列内的元素为递增排列,希尔排序算法执行完毕。

3 性能分析

3.1 稳定性

由于插入排序是将待排序元素顺次插入新的有序序列中,不会改变原数列中相同关键字元素的相对位置,所以我们说插入排序是稳定的。

希尔排序算法在进行每一轮排序时,只能保证组内元素有序,但在调整组内元素的时候,可能令分在两个组中且具有相同关键字的元素交换位置。例如:

// 对如下数组使用希尔排序,增量为希尔增量
// 第一轮排序结果如下:
// 排序前
[1, 49, 33, 49, 5, 62]
 1 ******** 49
 ** 49 ******** 5
 ****** 33 ******** 62

// 排序后
[1, 5, 33, 49, 49, 62]
 1 ******** 49
 ** 5 ******** 49
 ****** 33 ******** 62

在这个例子中,经过第一轮排序关键字为49的元素,在原数列中的相对位置已经发生了改变。

综上可知,希尔排序是不稳定的排序算法。

3.2 时间复杂度

希尔排序的时间复杂度是不确定的,设置不同的增量规则,会对希尔排序的性能造成很大影响。例如:在希尔增量下,希尔排序的时间复杂度为O(n2);在Hibbard增量下,希尔排序的时间复杂度为O(n(3/2));希尔排序时间复杂度下限为 n*log2n。

快速排序算法( O(n(log2n)) )在大规模数据情况下,通常比希尔排序表现更好,所以当数据量极大时,可以优先考虑使用快速排序代替希尔排序。但是,在确定增量的情况下,希尔排序在时间复杂度的表现通常比较稳定,极端情况的上下浮动小,因此普适性更强,可以作为排序算法的首选,在发现表现欠佳时,再考虑用其他算法替换。

4 javascript 代码实现

var arr = (function(len){
    if(!len) return [0];
    var arr = [];
    for(var i = len; i > 0; i--) arr.push(Math.floor( Math.random() * 100 ))
    return arr
})(10);
console.log("original arr : ",arr)
for(var fraction = Math.floor(arr.length / 2); fraction >= 1; fraction = Math.floor(fraction / 2)) {
    for(var i = fraction; i < arr.length; i++) {
        for(var j = i - fraction;j >= 0 && arr[j] > arr[j + fraction]; j -= fraction) {
            var temp = arr[j];
            arr[j] = arr[j + fraction];
            arr[j + fraction] = temp;
        }
    }
}
console.log("result : ",arr)

参考资料
[1] [百度百科] 希尔排序
[2] [Foliciatarier的博客] 希尔排序增量序列简介

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 一、直接插入排序 直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的元素记录,按其关键字...
    kevin16929阅读 546评论 0 0
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    闲云清烟阅读 756评论 0 6
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,164评论 0 52
  • http://codeguide.bootcss.com/ 规范化 HTML 重构 PSD 语义分析 PSD 结构...
    龙权阅读 223评论 0 0
  • 浊某人向来井底之蛙,不知海阔天空还常洋洋自得,自以为写了六十几万字就很了不起,这不,刚受教育了。 有一位简书作者向...
    化浊阅读 516评论 6 1