JavaScript数据结构26—希尔,堆,快速,归并排序

希尔和堆排序

//希尔排序(插入)
Array.prototype.shellSort = function(){
  var increment = this.length;
  console.info('初始化步长:'+increment);
  var temp,j;
  do{
    increment = parseInt(increment/3)+1;
    console.info('步长变为:'+increment);
    for (var i = increment; i < this.length; i++) {
      console.info('对比 第'+i+'个元素:'+this[i]+',第'+(i-increment)+'个元素:'+
        this[i-increment]);
      if(this[i]<this[i-increment]){
        temp = this[i];
        for(j = i-increment;j>=0&&temp<this[j];j-=increment){
          console.info('赋值 第'+(j+increment)+'个元素'+this[j+increment]
            +'赋值为第'+j+'元素'+this[j]);
          this[j+increment] = this[j];
        }
        this[j+increment] = temp;
        console.info('赋值 第'+(j+increment)+'个元素'+this[j+increment]
          +'赋值为第'+i+'元素'+temp);
      }
    }
  }
  while(increment>1);
}
//堆排序
//调整函数
Array.prototype.headAdjust = function(pos, len){
  //将当前节点值进行保存
  var swap = this[pos];
  //定位到当前节点的左边的子节点
  var child = pos * 2 + 1;
  //递归,直至没有子节点为止
  while(child < len){
    //如果当前节点有右边的子节点,并且右子节点较大的场合,采用右子节点
    //和当前节点进行比较
    if(child + 1 < len && this[child] < this[child + 1]){
      child += 1;
    }
    //比较当前节点和最大的子节点,小于则进行值交换,交换后将当前节点定位
    //于子节点上
    if(this[pos] < this[child]){
      this[pos] = this[child];
      pos = child;
      child = pos * 2 + 1;
    }
    else{
      break;
    }
    this[pos] = swap;
  }
}

//构建堆
Array.prototype.buildHeap = function(){
  //从最后一个拥有子节点的节点开始,将该节点连同其子节点进行比较,
  //将最大的数交换与该节点,交换后,再依次向前节点进行相同交换处理,
  //直至构建出大顶堆(升序为大顶,降序为小顶)
  for(var i=parseInt(this.length/2); i>=0; i--){
    this.headAdjust(i, this.length);
  }
}

Array.prototype.heapSort = function(){
  //构建堆
  this.buildHeap();
  //从数列的尾部开始进行调整
  for(var i=this.length-1; i>0; i--){
    //堆顶永远是最大元素,故,将堆顶和尾部元素交换,将
    //最大元素保存于尾部,并且不参与后面的调整
    var swap = this[i];
    this[i] = this[0];
    this[0] = swap;
    //进行调整,将最大)元素调整至堆顶
    this.headAdjust(0, i);
  }
}
var a1 = [3, 1, 5, 7, 2, 4, 9, 6, 10, 8];
console.log('希尔排序before: ' + a1);
a1.shellSort();
console.log('希尔排序after: ' + a1);
var a2 = [3, 1, 5, 7, 2, 4, 9, 6, 10, 8];
console.log('堆排序before: ' + a2);
a2.heapSort();
console.log('堆排序after: ' + a2);

希尔排序before: 3,1,5,7,2,4,9,6,10,8
初始化步长:10
步长变为:4
对比 第4个元素:2,第0个元素:3
赋值 第4个元素2赋值为第0元素3
赋值 第0个元素2赋值为第4元素2
对比 第5个元素:4,第1个元素:1
对比 第6个元素:9,第2个元素:5
对比 第7个元素:6,第3个元素:7
赋值 第7个元素6赋值为第3元素7
赋值 第3个元素6赋值为第7元素6
对比 第8个元素:10,第4个元素:3
对比 第9个元素:8,第5个元素:4
步长变为:2
对比 第2个元素:5,第0个元素:2
对比 第3个元素:6,第1个元素:1
对比 第4个元素:3,第2个元素:5
赋值 第4个元素3赋值为第2元素5
赋值 第2个元素3赋值为第4元素3
对比 第5个元素:4,第3个元素:6
赋值 第5个元素4赋值为第3元素6
赋值 第3个元素4赋值为第5元素4
对比 第6个元素:9,第4个元素:5
对比 第7个元素:7,第5个元素:6
对比 第8个元素:10,第6个元素:9
对比 第9个元素:8,第7个元素:7
步长变为:1
对比 第1个元素:1,第0个元素:2
赋值 第1个元素1赋值为第0元素2
赋值 第0个元素1赋值为第1元素1
对比 第2个元素:3,第1个元素:2
对比 第3个元素:4,第2个元素:3
对比 第4个元素:5,第3个元素:4
对比 第5个元素:6,第4个元素:5
对比 第6个元素:9,第5个元素:6
对比 第7个元素:7,第6个元素:9
赋值 第7个元素7赋值为第6元素9
赋值 第6个元素7赋值为第7元素7
对比 第8个元素:10,第7个元素:9
对比 第9个元素:8,第8个元素:10
赋值 第9个元素8赋值为第8元素10
赋值 第8个元素10赋值为第7元素9
赋值 第7个元素8赋值为第9元素8
希尔排序after: 1,2,3,4,5,6,7,8,9,10
堆排序before: 3,1,5,7,2,4,9,6,10,8
堆排序after: 1,2,3,4,5,6,7,8,9,10
[Finished in 0.1s]

快速排序

function quickSort(arr){
    //如果数组<=1,则直接返回
    if(arr.length<=1){
        return arr;
    }
    var pivotIndex=Math.floor(arr.length/2);
    //找基准,并把基准从原数组删除
    var pivot=arr.splice(pivotIndex,1)[0];
    //定义左右数组
    var left=[];
    var right=[];
    //比基准小的放在left,比基准大的放在right
    for(var i=0;i<arr.length;i++){
        if(arr[i]<=pivot){
            left.push(arr[i]);
        }
        else{
        right.push(arr[i]);
        }
    }
    //递归
    return quickSort(left).concat([pivot],quickSort(right));
}
var a1 = [3, 1, 5, 7, 2, 4, 9, 6, 10, 8];
console.log('排序before: ' + a1);
a1 = quickSort(a1);
console.log('排序after: ' + a1);

排序before: 3,1,5,7,2,4,9,6,10,8
排序after: 1,2,3,4,5,6,7,8,9,10

归并排序

function merge(left,right) {
    var result = [];
    while(left.length>0&&right.length>0){
        if(left[0]<right[0]){
            result.push(left.shift());
        }else{
            result.push(right.shift());
        }
    }
    return result.concat(left).concat(right);
}
function mergeSort(arr){
    if(arr.length==1){
        return arr;
    }
    var mid = Math.floor(arr.length/2);
    var left = arr.slice(0,mid);
    var right = arr.slice(mid);
    return merge(mergeSort(left),mergeSort(right))
}
var a1 = [3, 1, 5, 7, 2, 4, 9, 6, 10, 8];
console.log('排序before: ' + a1);
a1 = mergeSort(a1);
console.log('排序after: ' + a1);

排序before: 3,1,5,7,2,4,9,6,10,8
排序after: 1,2,3,4,5,6,7,8,9,10
[Finished in 0.1s]

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

推荐阅读更多精彩内容