JavaScript与数据结构

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

2017-04-12  本文已影响0人  RichardW

希尔和堆排序

//希尔排序(插入)
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]

上一篇下一篇

猜你喜欢

热点阅读