js--冒泡、选择、插入、快排、归并算法

本文详细介绍了JavaScript中的几种常见排序算法,包括选择排序、快速排序、冒泡排序、插入排序以及归并排序。重点讲解了快速排序在取基准值时为何要使用splice操作,以及各排序算法的基本思想和代码实现。
摘要由CSDN通过智能技术生成

选择排序

概念:选择排序大致的思路是找到数据结构中的最小值并将其放置在第一位,接着找到第二小的值并将其放在第二位,以此类推。
复杂度: O(n^2)

代码实现

var swap = function (array, index1, index2){
  var aux = array[index1];
  array[index1] = array[index2];
  array[index2] = aux;
}

var selectionSort = function(array) {
  var length = array.length, indexMin;// {1}声明一些将在算法内使用的变量
  for (var i = 0;i < length -1;i++) {// {2}外循环
    indexMin = i;// {3}假设本迭代轮次的第一个值为数组最小值
    for (var j = i;j < length;j++) {// {4}从当前i的值开始至数组结束
      if (array[indexMin] > array[j]) {// {5}我们比较是否位置j的值比当前最小值小
        indexMin = j; // {6};如果是,则改变最小值至新最小值
      }
    }
    if (i !== indexMin) {
      swap(array, i, indexMin); // {7}最后,如果该最小值和原最小值不同(行{7}),则交换其值。
    }
  } // 复杂度是O(n^2)
  return array;
}

快速排序

原理:从数组中取一个值为基准值,并将剩下的值与之比较,小于基准值的放到左边,大于基准值的放到右边,并再次对左右两边进行快速排序,直至左右两边只剩一个元素。
最坏时间复杂度:O(n^2) 当选择的基准值为最大值或最小值时
平均时间复杂度:O(n*log2n)
function quick(arr){
        var len=arr.length;
        if(len<=1){
            return arr;
        }
        var index=Math.floor(len/2),//向下取整 根据中间的值作为比较对象
                pindex=arr.splice(index,1)[0],//需要删除中间值,以缩小排序的数组大小
                left=[],//定义左右两个数组 左大右小
                right=[];
 
        for(var i=0;i<len-1;i++){ //遍历整个数组 大放右 小放左
            if(arr[i]>=pindex){
                right.push(arr[i]);
            }else{
                left.push(arr[i]);
            }
        }
        return quick(left).concat([pindex],quick(right)); //继续递归并将数组合并
    }
    alert(quick(arr));

注意:在取基准值的时候有的人可能会问:为什么要用splice把他取出来呢?直接用索引值引用对应的值就好了,原因在这里,如果我们没有把基准值提取出来的话,基准值也会做为一个值与基准值(它本身)进行比较,数组的整体大小没有改变,而我们把它提取出来之后可以减少数组的长度。当然我们也可以把数组的第一位作为基准值,在遍历时跳过,也是可以的。

冒泡:

 var arr = [29,45,51,68,72,97];
    //外层循环,控制趟数,每一次找到一个最大值
    for (var i = 0; i < arr.length - 1; i++) {
        // 内层循环,控制比较的次数,并且判断两个数的大小
        for (var j = 0; j < arr.length - 1 - i; j++) {
            // 白话解释:如果前面的数大,放到后面(当然是从小到大的冒泡排序)
            if (arr[j] > arr[j + 1]) {
                var temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
 
    }
    console.log(arr);//[2, 4, 5, 12, 31, 32, 45, 52, 78, 89]

插入:

function loop(arr) {
    for (let i = 1; i < arr.length; i++) {
        let comp = arr[i]
        let j = i - 1
        while (arr[j] > comp && j > 0) {
            arr[j + 1] = arr[j]
            j--
        }
        arr[j + 1] = comp
    }
    return arr
}

let test = [1, 9, 8, 6, 7, 6]
let newx = loop(test)
console.log(newx)

归并:

function mergeSort(arr) {
    const length = arr.length;
    if (length === 1) { //递归算法的停止条件,即为判断数组长度是否为1
        return arr;
    }
    const mid = Math.floor(length / 2);
   
    const left = arr.slice(0,  mid);
    const right = arr.slice(mid, length);
  
    return merge(mergeSort(left), mergeSort(right)); //要将原始数组分割直至只有一个元素时,才开始归并
}

function merge(left, right) {
    const result = [];
    let il = 0;
    let ir = 0;

    //left, right本身肯定都是从小到大排好序的
    while( il < left.length && ir < right.length) {
        if (left[il] < right[ir]) {
            result.push(left[il]);
            il++;
        } else {
            result.push(right[ir]);
            ir++;
        }
        
    }

    //不可能同时存在left和right都有剩余项的情况, 要么left要么right有剩余项, 把剩余项加进来即可
    while (il < left.length) { 
        result.push(left[il]);
        il++;
    }
    while(ir < right.length) {
        result.push(right[ir]);
        ir++;
    }
    return result;
}
console.log(mergeSort([2,9,1,8,3,]))
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值