前端必备算法--排序

排序算法

不同的场景中,不同的排序算法执行效率不同。

/**
 * 交换数组中指定的位置
 * @param {*} arr 
 * @param {*} i1
 * @param {*} i2 
 */
function swap(arr,i1,i2){
    var temp = arr[i1];
    arr[i1] = arr[i2];
    arr[i2] =temp;
}

选择排序

时间复杂度:O(N2)   稳定性:不稳定

一次选择排序,将某个区间的最小值排列到该区域的第一位
步骤:

  1. 找出该区域的最小值
  2. 将该值与该区域第一个值交换
  3. 对下一个区域重复上述过程,直到排序完成
/**
 * 选择排序
 * @param {*} arr 
 */
function selectionSort(arr) {
    for (var i = 0; i < arr.length - 1; i++) {
        //搞定i~arr.length-1区间
        //从该区间中找出最小值,和第i位交换
        var min = arr[i];//定义一个变量,为该区间的第一个数
        var index = i;//最小值所在的位置
        for(var j = i + 1; j < arr.length; j++){
            if(arr[j] < min){
                min = arr[j];
                index = j;//重新记录最小值的位置
            }
        }
        //最小值已经找出来
        //交换第i位和第index位
        swap(arr,i,index);
    }
}

冒泡排序

时间复杂度:O(N2)   稳定性:稳定

一次冒泡排序,可以将某个区域序列的最大值排序到该区域的最后一位
步骤:
1.将第1位和第2位比较,如果前者比后者大则交换
2.依次类推,直到比较到该区域的最后两位
3.重复上述过程,直到序列排序完成

/**
 * 冒泡排序
 * @param {*} arr 
 */
function bubbleSort(arr){
    for(var i = 0; i < arr.length - 1; i++){
        //需要经过arr.length次冒泡
        //循环0~arr.length-1-i
       for(var j = 0; j < arr.length - 1 - i; j++){
           if(arr[j] > arr[j + 1]){
               swap(arr , j , j + 1);
           }
           }
       }
}

插入排序

时间复杂度:O(N2)   稳定性:稳定
相较于顺序遍历会稍显繁琐,但当数列本身已近排序状态效率会更高

将序列分为两个部分,一部分是有序的,一部分是无序的,现在要做的是,就是不断的从无序的部分取出数据,加入到有序的部分,直到整个排序完成
例如:序列[5, 7, 2, 3, 6]

  1. 分为有序的序列和无序的序列 (5) (7 2 3 6)
  2. 不断的扩充有序序列 (5 7) (2 3 6)
  3. 不断的扩充有序序列 (2 3 5 6 7)
  4. 排序完成
/**
 * 插入排序
 * @param {*} arr 
 */
function insertionSort(arr){
    for(var i = 1; i < arr.length; i++){
        //只看比他小的才需要排序,比他大的不需要排序
        if(arr[i] < arr[i - 1]){
            //将第i位的值加入到前面的有序队列的正确位置
            var temp = arr[i];
            for(j = i; j >= 0; j--){
                if(j > 0 && arr[j -1] > temp){
                    arr[j] = arr[j -1];
                }else{
                    arr[j] = temp;
                    break;
                }
            } 
        }
    }
}

快速排序

时间复杂度:O(NlogN)   稳定性:不稳定

选择一个数(比如序列的最后一位)作为基准数,将整个序列排序成两部分,一部分比该数小,另一部分比该数大,基准数在中间,然后对剩余的序列做同样的事情,直到排序完成
例如:序列[5, 7, 2, 3, 6, 4]

  1. 选择4作为基准数,排序成为:(3, 2) 4 (7, 6, 5)
  2. 对于3,2, 继续使用该方式排序,得到: (2, 3) 4 (7,6,5)
  3. 对于7,6,5,继续使用该方式排序,得到: (2, 3) 4 (5,6,7)
  4. 排序完成
/**
 * 快速排序
 * @param {*} arr 
 */
function quickSort(arr){
    /**
     * 对数组的某个区域进行一次快速排序
     * @param {*} arr 
     * @param {*} start  区域的起始下标
     * @param {*} end   区域的结束下标
     */
    function _quickSort(arr, start, end){
        if ( start >= end || start > arr.length -1)   return;
        var low = start,high = end;
        var key = arr[end]; //基准值
        while (low < high){
            while (low < high && arr[low] <= key)    low++;
            arr[high] = arr[low];
            while (low < high && arr[high] <= key)   high--; 
            arr[low] = arr[high];
        }
    //  low == high     
        arr[low] = key;
        _quickSort(arr, start, low - 1);//对前面的数进行快排
        _quickSort(arr, low + 1, end);//对后面的数进行快排
    }
    _quickSort(arr, 0 ,arr.length - 1);
        
}

测试数据

var arr = [5 ,3 ,1 ,4 ,7 ,6 ];
selectionSort(arr);
console.log(arr);
bubbleSort(arr);
console.log(arr);
insertionSort(arr);
console.log(arr);
quickSort(arr);
console.log(arr);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值