js数组排序的六种方法

Posted 下雨打伞干嘛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js数组排序的六种方法相关的知识,希望对你有一定的参考价值。

1. sort()排序

sort() 方法用于对数组的元素进行排序。

排序顺序可以是字母或数字,并按升序或降序。默认排序顺序为按字母升序。

注意: 当数字是按字母顺序排列时"40"将排在"5"前面。因为“40”中的"4"小于“5”。

使用数字排序,你必须通过一个函数作为参数来调用。函数指定数字是按照升序还是降序排列。

注意: 这种方法会改变原始数组!。

	// sort排序
    const sortArr = [5,2,1,3,6,8,4,5,7,0,15];
    const sortAns = sortArr.sort();
    console.log(sortAns,'----------------------sort排序');
    // [0, 1, 15, 2, 3, 4, 5, 5, 6, 7, 8] '----------------------sort排序'

    const sortArr1 = [5,2,1,3,6,8,4,5,7,0,15];
    const sortAns1 = sortArr1.sort((a,b)=>return a-b);
    console.log(sortAns1,'----------------------sort1排序');
    // [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 15] '----------------------sort1排序'
    
    const sortArr2 = ["Banana", "Orange", "Apple", "Mango"];
    const sortAns2 = sortArr2.sort();
    console.log(sortAns2,'----------------------sort2排序');
    // ['Apple', 'Banana', 'Mango', 'Orange'] '----------------------sort2排序'

2. 选择排序

原理:将未排序的数据的第一个数据作为对比基准,在除了已排序和基准数据以外的数据里找到最小的数据,将该数据和基准数据进行交换。
以 const choseArr = [5,2,1,3,6,8,4,5,7,0,15]; 为例。
此时 choseArr 中的数据都未进行排序,所以下标为 0 的数据 5 作为第一次排序的基准,从下标为 1 的数据 2 开始进行找到最小的数据,和基准数据 5 进行交换。
第一次交换完成后的 choseArr = [0,2,1,3,6,8,4,5,7,5,15];
第二次排序,以剩下未排序的第一个数据作为基准,就是下标为 1 的数据 2 ,从下标为 2 的数据 1 开始进行查找最小的数据,和基准数据 2 进行交换。
第二次交换完成后的 choseArr = [0,1,2,3,6,8,4,5,7,5,15];
重复以上步骤即可得到完整排序。

	// 选择排序
    const choseArr = [5,2,1,3,6,8,4,5,7,0,15];
    for (let i = 0; i < choseArr.length-1; i++) 
      let minIndex = i; //用于存储最小值的下标,排序刚开始时,假设最小值的下标就是选中的基准数据下标
      for (let j = i+1; j < choseArr.length; j++) 
        if (choseArr[j] < choseArr[minIndex]) 
          minIndex = j;
        
      
      [choseArr[i],choseArr[minIndex]] = [choseArr[minIndex],choseArr[i]]
    
    console.log(choseArr,'----------------------选择排序');
    // [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 15] '----------------------选择排序'

推荐视频:小伙教你,5分钟学会 JS中的选择排序

3. 快速排序

原理:取数组的中间值为基准数据,把数组中剩余的小于基准数据的数据放在基准数据的左边的新数组中,大于的放在右边的新数组中,再分别将这两个新数组按照原数组取中间值,划分左右新数组的方法进行递归,最后即可得到排序好的数组。
以 const quickArr = [5,2,1,3,6,8,4,5,7,0,15]; 为例。
第一次排序的基准数据是下标为 5 的数据 8,将小于 8 的剩余数据放入 leftArr 新数组中,将大于 8 的数据放入 rightArr 的新数组中,重复上述步骤。

	// 快速排序
    const quickArr = [5,2,1,3,6,8,4,5,7,0,15];
    function quickFun(params) 
    	//当进行递归的数组的长度小于等于 1 的时候直接返回该数组
      if (params.length <= 1) 
        return params;
      
      let middleIndex = Math.floor(params.length / 2); //获取基准数据的下标
      let middleItem = params.splice(middleIndex,1)[0]; //截取基准数据
      let leftArr = [];
      let rightArr = [];
      for (let k = 0; k < params.length; k++) 
        if (params[k] > middleItem) 
          rightArr.push(params[k]);
        else
          leftArr.push(params[k]);
        
      
      return quickFun(leftArr).concat(middleItem,quickFun(rightArr)); //将左边数组,基准数据和右边数组进行拼接成一个完整的数组
    
    const quickAns = quickFun(quickArr);
    console.log(quickAns,'----------------------快速排序');
    // [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 15] '----------------------快速排序'

推荐视频:javascript 实现快速排序

4. 冒泡排序

原理:数组中的数据前后两两进行对比,如果后面一个数据小于前面一个则进行交换。
以 const popArr = [5,2,1,3,6,8,4,5,7,0,15]; 为例。
因为 5 > 2 ,所以进行交换:[2,5, 1,3,6,8,4,5,7,0,15];
因为 5 > 1 ,所以进行交换:[2,1,5, 3,6,8,4,5,7,0,15];
因为 5 > 3 ,所以进行交换:[2,1,3,5, 6,8,4,5,7,0,15];
因为 5 < 6 ,所以不进行交换:[2,1,3,5,6,8,4,5,7,0,15];
因为 6 < 8 ,所以不进行交换:[2,1,3,5,6,8,4,5,7,0,15];
因为 8 > 4 ,所以进行交换:[2,1,3,5,6,4,8, 5,7,0,15];
因为 8 > 5 ,所以进行交换:[2,1,3,5,6,4,5,8, 7,0,15];
因为 8 > 7 ,所以进行交换:[2,1,3,5,6,4,5,7,8, 0,15];
因为 8 > 0 ,所以进行交换:[2,1,3,5,6,4,5,7,0,8, 15];
至此第一遍排序结束,进行下一轮排序。

	// 冒泡排序
    const popArr = [5,2,1,3,6,8,4,5,7,0,15];
    // 因为是前后两两排序,所以只需要数组长度-1 次遍历即可
    for (let g = 0; g < popArr.length-1; g++) 
      for (let h = 0; h < popArr.length-1; h++) 
        if (popArr[h] > popArr[h+1]) 
          [popArr[h],popArr[h+1]] = [popArr[h+1],popArr[h]];
        
      
    
    console.log(popArr,'----------------------冒泡排序');
    // [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 15] '----------------------冒泡排序'

推荐视频:JS冒泡排序

5. 插入排序

原理:以数组的第一个数据为基准,想象成一个只有一个数据的数组,将剩下的数据依次插入基准数据所在的数组中合适的位置。
以 const pickArr = [5,2,1,3,6,8,4,5,7,0,15]; 为例。
基准数据为下标是 0 的数据 5,将基准数据想象成一个数组即:[5] ,第一次遍历需要进行插入的数据时下标为 1 的数据 2,因为 2 < 5 ,所以将 2 插入到 5 之前,即:[2,5]。剩下的数据重复以上操作即可。

	// 插入排序
    const pickArr = [5,2,1,3,6,8,4,5,7,0,15];
    function pickFun(params)
      let preIndex = 0; // 进行大小对比的基准数据的下标
      let current = 0; // 进行大小对比的当前选中的剩余数量值
      for (let g = 1; g < params.length; g++) 
        preIndex = g - 1; // 进行基准数据赋值
        current = params[g]; // 获取当前进行对比的剩余数量值
        while(preIndex >= 0 && params[preIndex] > current)
          params[preIndex+1] = params[preIndex];
          preIndex--;
        
        params[preIndex+1] = current;
      
      return params;
    
    const pickAns = pickFun(pickArr);
    console.log(pickAns,'----------------------插入排序');
    // [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 15] '----------------------插入排序'

推荐视频:JS插入排序

6. 希尔排序

原理:基于插入排序进行的优化,先将整个数组按照数组长度的一半进行分组使用插入排序,完成后,再将整个数组按照数组长度的1/4进行分组使用插入排序,重复以上步骤,直到分组长度为1为止。
以 const hillArr = [5,2,1,3,6,8,4,5,7,0,15]; 为例。
hillArr 数组的长度为 11 ,向下取整得到 5,因此以 5 为间隔进行分组得到:[5,8,15] [2,4] [1,5] [3,7] [6,0];在分好的数组中分别进行插入排序,可得:[5,8,15] [2,4] [1,5] [3,7] [0,6];
再将得到的数组按照 5 的间隔进行还原得到 [5, 2, 1, 3, 0, 8, 4, 5, 7, 6, 15];再将 5 进行除 2 并取整得到的数据作为下一轮的间隔数据进行对数组进行分组,对分组后的数组分别再使用插入排序,重复以上步骤。

	// 希尔排序
    const hillArr = [5,2,1,3,6,8,4,5,7,0,15];
    function hillFun(arr)
      //第一层循环,确定间隔数
      // 这里的 gap 相当于插入排序中的 1 ,所以在第二层循环中 preIndex = i-gap; 相当于插入排序中的 preIndex = g - 1;
      for(let gap = parseInt(arr.length/2); gap > 0 ; gap = parseInt(gap/2))
        //第二层循环,使用插入排序
        for(let i = gap ; i < arr.length ; i++)
          let preIndex = i-gap;
          let current = arr[i]
          while(preIndex >=0 && current < arr[preIndex])
              arr[preIndex + gap] = arr[preIndex];
              preIndex -= gap;
          
          arr[preIndex+gap] = current
        
      
      return arr;
    
    const hillAns = hillFun(hillArr);
    console.log(hillAns,'----------------------希尔排序');
    // [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 15] '----------------------希尔排序'

推荐视频:[算法]六分钟彻底弄懂希尔排序,简单易懂

JS数组去重的六种方法

一、利用ES6 Set去重(ES6中最常用)

function unique (arr) {
  return Array.from(new Set(arr))
}
var arr = [1,1,‘true‘,‘true‘,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN‘, 0, 0, ‘a‘, ‘a‘,{},{}];
console.log(unique(arr))
 //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
不考虑兼容性,这种去重的方法代码最少。这种方法还无法去掉“{}”空对象,后面的高阶方法会添加去掉重复“{}”的方法。

二、利用for嵌套for,然后splice去重(ES5中最常用)

function unique(arr){            
        for(var i=0; i<arr.length; i++){
            for(var j=i+1; j<arr.length; j++){
                if(arr[i]==arr[j]){         //第一个等同于第二个,splice方法删除第二个
                    arr.splice(j,1);
                    j--;
                }
            }
        }
return arr;
}
var arr = [1,1,‘true‘,‘true‘,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN‘, 0, 0, ‘a‘, ‘a‘,{},{}];
    console.log(unique(arr))
    //[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}]     //NaN和{}没有去重,两个null直接消失了

双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。

三、利用indexOf去重

function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log(‘type error!‘)
        return
    }
    var array = [];
    for (var i = 0; i < arr.length; i++) {
        if (array .indexOf(arr[i]) === -1) {
            array .push(arr[i])
        }
    }
    return array;
}
var arr = [1,1,‘true‘,‘true‘,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN‘, 0, 0, ‘a‘, ‘a‘,{},{}];
console.log(unique(arr))
   // [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]  //NaN、{}没有去重
新建一个空的结果数组,for 循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组。

四、利用sort()

function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log(‘type error!‘)
        return;
    }
    arr = arr.sort()
    var arrry= [arr[0]];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] !== arr[i-1]) {
            arrry.push(arr[i]);
        }
    }
    return arrry;
}
     var arr = [1,1,‘true‘,‘true‘,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN‘, 0, 0, ‘a‘, ‘a‘,{},{}];
        console.log(unique(arr))
// [0, 1, 15, "NaN", NaN, NaN, {…}, {…}, "a", false, null, true, "true", undefined]      //NaN、{}没有去重

利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。

五、利用递归去重

function unique(arr) {
        var array= arr;
        var len = array.length;

    array.sort(function(a,b){   //排序后更加方便去重
        return a - b;
    })

    function loop(index){
        if(index >= 1){
            if(array[index] === array[index-1]){
                array.splice(index,1);
            }
            loop(index - 1);    //递归loop,然后数组去重
        }
    }
    loop(len-1);
    return array;
}
 var arr = [1,1,‘true‘,‘true‘,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN‘, 0, 0, ‘a‘, ‘a‘,{},{}];
console.log(unique(arr))
//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]



六、利用Map数据结构去重

function arrayNonRepeatfy(arr) {
  let map = new Map();
  let array = new Array();  // 数组用于返回结果
  for (let i = 0; i < arr.length; i++) {
    if(map .has(arr[i])) {  // 如果有该key值
      map .set(arr[i], true); 
    } else { 
      map .set(arr[i], false);   // 如果没有该key值
      array .push(arr[i]);
    }
  } 
  return array ;
}
 var arr = [1,1,‘true‘,‘true‘,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN‘, 0, 0, ‘a‘, ‘a‘,{},{}];
    console.log(unique(arr))
//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]
 

以上是关于js数组排序的六种方法的主要内容,如果未能解决你的问题,请参考以下文章

JS定义类的六种方式详解

JS定义类的六种方式详解

JavaScript 常见的六种继承方式

详解前端异步编程的六种方案

JavaScript常见的六种继承方式

算法的六种排序