js常用的5大排序

138 阅读2分钟

1、冒泡排序

描述:最简单的排序,运行时间长

原理:从第一个开始和后面一项进行比较,较大的放在后面,直到把最大的放在最后。比较相邻的项,如果第一个比第二个大,则交换,上移至正确的排序。

代码:

function sort1(arr) {
    for (let i = 0; i < arr.length; i++) {
      for (let j = 0; j < arr.length - 1 - i; j++) {
        if (arr[j] > arr[j + 1]) {
          [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];//解构赋值
        }
      }
    }
    return arr;
  }

复杂度:时间复杂度O(n^2),空间复杂度O(1)

2、选择排序

描述:原地址比较排序算法

原理:找到数据结构中的最小值,并将其放在第一位,接着找到第二个,放在第二位,以此类推。

代码:

unction sort2(arr){
    let len=arr.length;
    for(let i=0;i<len-1;i++){
        let min=i;
        for(let j=i;j<len;j++){
            if(arr[min]>arr[j]){
                min=j;
            }
        }
        if(min!=i){
            [arr[min], arr[i]] = [arr[i], arr[min]];
        }
    }
    return arr;
}

复杂度:时间复杂度O(n^2),空间复杂度O(1)

3、插入排序

描述:排小型数组的时候比冒泡和选择要好

原理:插入排序每次排一个数组项。从第二个开始,一次与之前的数进行比较后,选择合适位置插入。

代码:

function sort3(arr){
    let len=arr.length,temp;
    for(let i=1;i<len;i++){
        let j=i;
        temp=arr[i];//当前要插入的项
        while(j>0&&arr[j-1]>temp){
            arr[j]=arr[j-1];
            j--;
        }
        arr[j]=temp;
    }
    return arr;
}

复杂度:时间复杂度O(n^2),空间复杂度O(1)

4、归并排序

描述:第一个实际使用的排序

原理:分治算法,将原始数组切分成较小的数组,直到每个小数组只有一个位置,将小数组归并成较大的数组,直到最后只有一个排序完成的大数组。

代码:

//分递归
function mergeSortRec (array){
    var length=array.length;
    if(length==1){
        return array;
    }//停止条件,长度为1
    var mid = Math.floor(length/2),
    left=array.slice(0,mid),
    right=array.slice(mid,length);
    return merge(mergeSortRec(left),mergeSortRec(right));
}
//合
var merge=function(left,right){
    var result=[],il=0,ir=0;
    while(il<left.length&&ir<right.length){
        if(left[il]<right[ir]){//左右比较后按序放入新数组
            result.push(left[il++]);
        }else{
            result.push(right[ir++]);
        }
    }
    while(il<left.length){//剩余左侧
        result.push(left[il++]);
    }
    while(ir<right.length){//剩余右侧
        result.push(right[ir++]);
    }
    return result;
}

复杂度:时间复杂度O(nlongn),空间复杂度O(n)

5、快速排序

描述:最常用的排序算法

原理:(1)将原始数组划分为较小的数组,将数组中间项作为主元,创建两个指针,左指针指向数组的第一项,右指针指向数组的最后一项。移动左指针,直到找到第一个比主元大的元素,接着,移动右指针直到找到第一个比主元小的元素,然后交换,重复这个过程,直到左指针超过了右指针。(2)对划分后的两个数组再次重复上述操作,直到数组完全排序。

代码:

var quick = function(array,left,right){
    var index;
    if(array.length>1){
        index = partition(array,left,right);
        if(left<index-1){
            //递归左边排序
            quick(array,left,index-1);
        }
        if(index<right){
            //递归右边排序
            quick(array,index,right);
        }
    }
    return array;
}
//左右分别交换
var partition=function(array,left,right){
    var pivot=array[Math.floor((right+left)/2)],i=left,j=right;
    while(i<=j){
        while(array[i]<pivot){
            i++;
        }
        while(array[j]>pivot){
            j--;
        }
        if(i<=j){
            //交换
            [array[i],array[j]]=[array[j],array[i]];
            i++;
            j--;
        }
    }
    return i;
}
console.log(quick(arr,0,arr.length-1)) ;

复杂度:时间复杂度O(nlongn),空间复杂度O(n)

\