排序算法——JS算法完成

排序 Sorting

排序基础概念

排序是计算机程序设计中的一种主要操纵,他的功用是将一个数据元素(或纪录)的恣意分列,从新分列成一个按关键字有序的序列。
待排序的纪录序列中能够存在两个或两个以上的关键字相称的纪录,且在排序前Ri在Rj前面(即i<j),若在排序后的序列中Ri任然在Rj前面,则称所用的排序算法
是稳固的。

假如根据排序过程当中根据的差别准绳对内部排序举行分类,则可分为

  1. 插进去排序

  2. 交流排序(疾速排序)

  3. 挑选排序

  4. 合并排序

  5. 基数排序

假如根据工作量来辨别能够分为3类

  1. 简朴的排序算法,时候复杂度为O(n2)

  2. 先进的排序算法,时候复杂度为O(nlogn)

  3. 基数排序,时候复杂度为O(d*n)

一般,在排序的过程当中须要举行以下两种基础操纵,(个中第二种操纵能够经由过程转变纪录的存储体式格局来予以防止)

  1. 比较两个关键字大小

  2. 将纪录从一个位置挪动至另一个位置
    待排序的纪录序列可有以下3种存储体式格局。

  3. 存储在地点一连的一组存储单元上。

  4. 静态链表,纪录之间的序次由指针指导,则完成排序不须要挪动纪录

  5. 待排序纪录存储在一组地点一连的存储单元内,同时,另外设一个指导各个纪录存储位置的地点向量,在排序过程当中不挪动纪录自身,而是挪动地点向量
    中这些纪录的“地点”,在排序完毕后再根据地点向量中的值调解纪录的存储位置。

插进去排序

直接插进去排序 O(n2)

最为简朴的一种排序,基础操纵为将一个纪录插进去到已排好序的有序表中,从而获得一个新的,纪录增1的有序表。

//直接插进去排序,更加高效的应该是折半插进去排序¬≥
function insertSort (Arr) {
  if (Arr.length <= 1) {
    return Arr;
  }
  var temp;

  for (var i = 1; i < Arr.length; i++) { //从1最先,第一个不必排序
    temp = Arr[i]; //用temp缓存待插进去的元素
    for (var j = i; j >= 0; j--) {
      if (temp < Arr[j]) {
        Arr[j + 1] = Arr[j]; //当Arr[i]<Arr[j],则将Arr[j]往后移一名
      } else if (temp > Arr[j]) {
        break; //第一种:假如找到了一个比Arr[i]小的Arr[j],则退出轮回,完毕
      }
      //第二种,当j轮回,完毕
    }
    //完毕j轮回,将temp中缓存的待插进去元素插进去
    Arr[j + 1] = temp;
  }

}; //insert完毕

其他插进去排序

  1. 折半插进去排序 O(n2) 经由过程削减比较关键字大小次数来优化排序算法。

  2. 2路插进去排序

  3. 表插进去排序

希尔排序 O(n3/2)

又被称为”减少增量排序”。基础思想:先将全部待排纪录序列分割成多少个子序列离别举行直接插进去排序,待全部序列中的纪录
“基础有序”时,再对全部纪录举行一次直接插进去排序。

function shellSort(Arr) {
  var gap = Math.floor(Arr.length / 2);
  while (gap > 0) {
    for (var i = 0; i < Arr.length; i++) {
      var temp = Arr[i];
      for (var j = i; j >= gap && Arr[j - gap] > temp; j -= gap) {
        Arr[j] = Arr[j - gap];
      }
      Arr[j] = temp;
    }
    gap = Math.floor(gap / 2);
  }
  return Arr;
}; //shell完毕

疾速排序

起泡排序 bubble sort

// 起泡排序,
function bibbleSort(Arr) {
  for (var i = Arr.length - 1; i >= 0; i--) {
    for (var j = 0; j < i; j++) {
      if (Arr[j] > Arr[j + 1]) {
        swap(j, j + 1, Arr);
      }
    }
  }
  return Arr;
};

疾速排序 quick sort

// 一趟疾速排序的算法是
// 1.设置初始值x=0,y=n-1,令keyValuey=Arr[0],2.从Arr[y]最先向前遍历,假如keyValue>Arr[y],则将Arr[i]和Arr[y]交流,3.从Arr[x]向后遍历,当keyValue<Arr[x]时;举行Arr[i]和Arr[y]交流,4.完毕前提为x==y;

function quickSort (Arr) {
  if (Arr.length <= 1) {
    return Arr;
  }
  var pivotIndex = Math.floor(Arr.length / 2);
  var pivot = Arr.splice(pivotIndex, 1);
  var leftArr = [];
  var rightArr = [];
  for (var i = 0; i < Arr.length; i++) {
    if (Arr[i] < pivot) {
      leftArr.push(Arr[i]);
    } else {
      rightArr.push(Arr[i]);
    }
  }
  return quickSort(leftArr).concat(pivot, quickSort(rightArr));
  //quickSortOnce完毕
}; //quick完毕

挑选排序

简朴的挑选排序

//挑选排序 从待排序的数组中找出最小值放在最前面
function selectSort(Arr) {
  for (var i = 0; i < Arr.length; i++) {
    for (var j = i; j < Arr.length; j++) {
      if (Arr[i] > Arr[j]) {
        swap(Arr, i, j);
      }
    }
  }
  return Arr;
}; //select完毕

树形挑选排序

堆排序 heap sort

留!!!

合并排序 merging sort O(m+n)

假定初始序列寄义n个纪录,则能够看成是n个有序的子序列,每个子序列的长度为1,然后两两合并,比及Math.floor(n/2)个长度为2或1的有序子序列,再两两合并,云云反复,直至获得一个长度为n的有序序列为止。

function mergeSort (){
    var merge=function(left,right){
        var final=[];
        while(left.length&&right.length){
            final.push(left[0]<=right[0]?left.shift():right.shift());
        }
        return final.concat(left.concat(right));
    };

    var len=this.length;
    if(len<2){
        return this;
    }

    var mid=parseInt(len/2),
        _left=this.slice(0,mid),
        _right=this.slice(mid);
    return merge(_left.mergeSort(),_right.mergeSort());
};

基数排序 radix Sorting

种种排序算法比较

以上用到的swap函数


//swap函数
function swap(Arr, firPos, secPos) {
  var temp = Arr[firPos];
  Arr[firPos] = Arr[secPos];
  Arr[secPos] = temp;
  return Arr; //返回天生的数组
} //swap完毕
    原文作者:WilsonLiu95
    原文地址: https://segmentfault.com/a/1190000006107040
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞