美文网首页
前端开发中常见排序算法

前端开发中常见排序算法

作者: 泰然自若_750f | 来源:发表于2020-06-17 17:58 被阅读0次

    冒泡排序

    思路: 从索引0开始 依次和下一个元素比较,如果前面元素大于后面的(升序)就交换位置。循环完成后比较下一轮。
    优化:添加一个标志位,如果单轮循环中没有发生位置交换,就说明已经是有序的,则排序结束。可以
    将时间复杂度 在最佳状态时降低到O(n)(本身就是一个有序数组)
    时间复杂度:O(n) 至 O(n^2)
    代码实现

       let arr = [30, 32, 6, 24, 37, 32, 45, 21, 38, 23, 47],conut=0;
    /**
     * 冒泡排序
     * @param {*} arr 
     */
    function bubbleSort(arr){
        for(let i=0;i<arr.length;i++)
        {
            let hasSrap=false; // 没有发生过交换的标识
            for(let j=0;j<arr.length-i;j++)
            {
                if(arr[j]>arr[j+1])
                {
                    //交换元素位置
                     [arr[j],arr[j+1]]=  [arr[j+1],arr[j]];
                     //发生过交换
                     hasSrap=true;
                }
                conut++;
            }
            //如果没有发生过交换
            if(!hasSrap)
            {
              return arr;
            }
    
        }
        return arr;
         
    }
    console.log(bubbleSort(arr)); //[ 6, 21, 23, 24, 30, 32, 32, 37, 38, 45, 47 ]
    console.log(`循环次数:${conut}`) //60
    

    选择排序

    思路::循环数组中的每一项,依次遍历后面的元素,选出后面元素与之相比最小的和当前元素交换位置
    时间复杂度: O(n^2)
    代码实现:

    //选择排序
    let arr = [30, 32, 6, 24, 37, 32, 45, 21, 38, 23, 47],conut=0;
    function selectedSort(arr){
        for(let i=0;i<arr.length;i++)
        {
            let n=i+1,index=i;
            while(n<arr.length){
                //依次找 取得比 当前被比较元素最小的索引
                if(arr[index]>arr[n])
                {
                    index=n;        
                }
                n++;
                conut++;
            }
            //交换位置
            [arr[i],arr[index]]=[arr[index],arr[i]];
        }
        return arr;
    
    }
    
    console.log(selectedSort(arr));  //[ 6, 21, 23, 24, 30, 32, 32, 37, 38, 45, 47 ]
    console.log(`循环次数:${conut}`) //55
    

    插入排序

    思路:循环元素,比较当前元素 找到某一位置与被比较元素小,和比该位置元素后一位大的,然后插入。
    例如:[1,2,5,4,5,32]:循环到 索引3,值为 4的位置。 4与5比较,小于 ,5后移,此时数组 为【1,2,5,5】,
    然后接着比较 2与4比较 小于4,则不需要继续插入了。插入 为【1,2,4,5,32】
    复杂度: O(n^2)

    let arr = [30, 32, 6, 24, 37, 32, 45, 21, 38, 23, 47],conut=0;
    function insertSort(arr){
        
        for(let i=0;i<arr.length;i++)
        {
          
            let j=i-1, //需要比较元素的前一个索引
                value=arr[i], //当前需要比较的值
                flag=true;  //是否需要再次遍历
            while(flag && j>=0)
            {
              //如果 大于需要比较的元素
              if(arr[j]>value)
              {
                //该元素后移
                 arr[j+1]=arr[j]
                 j--;
              }
              else{
                 //此时表示前后没有交换了,说明之前已经是有序数组,不需要再遍历
                  flag=false;
              }
            conut++;
            }
           
            //将比较的元素插入至索引
            arr[j+1]=value;
        }
        return arr;
    
    
      }
    console.log(insertSort(arr));
    console.log(`循环次数:${conut}`) //28
    

    快速排序

    思路:根据一个基数,然后将比基数小的值放在基数的左边,将比基数大的值放在基数的右边,之后进行递归那两组已经归类好的数组。
    时间复杂度:O(nlogn)

    /**
     * 快速排序
     * 
     * @param {*} arr 
     */
    function quickSort(arr){
        if(arr.length<2)
        {
          return arr;
        }
        //小于当前元素的放在左边,大于的放在右边数组
        let left=[],right=[],temp=arr[0];
        for(let i=1;i<arr.length;i++)
        {
            if(arr[i]<temp)
            {
              left.push(arr[i])
            }
            else{
              right.push(arr[i])
            }
            conut++;
        }
        //递归
        return quickSort(left).concat([temp],quickSort(right))
         
    }
    console.log(quickSort(arr));
    console.log(`循环次数:${conut}`)
    

    归并排序

    思路:递归分割数组,然后比较两个数组互相比较。比较时候的数组内部是有序的,依次比较,最后比较的数组长度越来越大。
    不好描述也不容易理解,看以下例子的描述。
    //直到两个数组 有一个被取空
    // [3,9,10] [2,6,7,8]
    //第一轮 3和 2比较 2小 从右边数组 取出 result=[2] L [3,4,5] R Z中 [6,7,8]
    // 3 和6 比较 左小 左边数组 出对列 result=[2,3] L:[9,10] R:[6,7,8]
    // 9 和 6 比较 右小 右边数组出对列 result=[2,3,6] L:[9,10] R:[7,8]
    // 9 和 7 比较 右小 右边数组出对列 result=[2,3,6,7] L:[9,10] R:[8]
    // 9 和 8 比较 右小 右边数组出对列 result=[2,3,6,7,8] L:[9,10] R:[]
    // 比较结束
    // result 和剩余元素合并
    时间复杂度:O(nlogn)

    let arr = [30, 32, 6, 24, 37, 32, 45, 21, 38, 23, 47],conut=0;
    function mergeSort(unsorted) {
      function merge(leftArr, rightArr) {
        let result = [];
        //直到两个数组 有一个被取空
        // [3,9,10] [2,6,7,8] 
        //第一轮 3和 2比较 2小 从右边数组 取出 result=[2]  L [3,4,5] R Z中 [6,7,8]
        // 3 和6 比较 左小 左边数组 出对列  result=[2,3] L:[9,10] R:[6,7,8]
        // 9 和 6 比较 右小 右边数组出对列  result=[2,3,6] L:[9,10] R:[7,8]
        // 9 和 7 比较 右小 右边数组出对列  result=[2,3,6,7] L:[9,10] R:[8]
        // 9 和 8 比较 右小 右边数组出对列  result=[2,3,6,7,8] L:[9,10] R:[]
        // 比较结束
        // result 和剩余元素合并
        while(leftArr.length>0 && rightArr.length>0)
        {
             if(leftArr[0]<rightArr[0])
             {
                  result.push(leftArr.shift());  
             }
             else{
                   result.push(rightArr.shift());
             }
        }
        //合并剩余元素
        leftArr &&(result=result.concat(leftArr));
        rightArr&&(result= result.concat(rightArr)) ;
         return result;
      }
      //分割数组,然后依次比较 
      function split(array) {
        const len = array.length;
        if (len <= 1) {
          return array;
        }
        //依次取中值
        const mid = Math.floor(len / 2);
        const leftArr = array.slice(0, mid);
        const rightArr = array.slice(mid, len);
        //分割元素 不断递归比较
        return merge( split(leftArr), split(rightArr) );
      }
      
      return split(unsorted);
    }
    
    
    console.log(mergeSort(arr))
    

    相关文章

      网友评论

          本文标题:前端开发中常见排序算法

          本文链接:https://www.haomeiwen.com/subject/jtisxktx.html