JS归并排序算法学习笔记

对一个一维数组进行排序。(使用归并排序算法)

思路:

将一个数组进行排序。不断的进行切割,知道单位为一。则停止切割。

然后将其合并,再进行排序。

(即分割,再进行合并)

图的引用:https://www.cnblogs.com/chengxiao/p/6194356.html。(感谢该链接作者的介绍)。

JS的实现:(个人实现)

    // 进行归并排序
    function gb(arr){  //归并排序
        let l= arr.length
        if(l==1){
            return arr[0]
        }
        let mid = Math.floor(l/2);  //获得了一个中间值
        //进行切割;
        let leftvalue = arr.slice(0,mid);  //左侧的数据
        let rightvalue = arr.slice(mid,l); //右侧的数据
      let final_left =  gb(leftvalue);  //分割到底的数据
      let final_right = gb(rightvalue); //分割到底的数据
      let result = hb(final_left,final_right);
      return result
        
    }
    function hb(arr01,arr02){       //合并
        let i=0; //记录数组一遍历的索引
          let j=0;//记录数组二变脸的索引
          let result =[];//接收合并结果;
          //同为数据的处理
        if(!(arr01 instanceof Array || arr02 instanceof Array)){
            if(arr01>arr02){
                result.push(arr02);
                result.push(arr01);
            }else{
                result.push(arr01);
                result.push(arr02);
            }
            return result;
        }
// 一个数组,一个数据的处理
        if(!((arr01 instanceof Array && arr02 instanceof Array) || (typeof arr01 =='number' && typeof arr02 == "number"))){
            
            if(arr01 instanceof Array) {
              result = arr01.slice(0);
                for(let i in arr01){
                    if(arr02>arr01[i]){
                        // result.splice(i+1,0,arr02);
                        // break;
                        if(i==arr01.length-1){ //已经到达尾部了
                            resul.splice(i+1,0,arr02);
                            break;
                        }
                    }else{
                        // result.unshift(arr02);
                        // break;
                        result.splice(i,0,arr02)
                        break
                    }
                }
                return result
            }else{
                //进入死循环
                result = arr02.slice(0);
                for(let i in arr02){
                    if(arr01>arr02[i]){
                        // result.splice(i+1,0,arr01);
                        // break;
                        if(i==arr02.length-1){ //已经到达尾部了
                            result.splice(i+1,0,arr01);
                            break;
                        }
                        continue;
                    }else{
                        // result.unshift(arr01);
                        result.splice(i,0,arr01)
                        break
                    }
                }
                return result
                
            }


        }

        // 两个数据都是数组的处理; 
          while(i<arr01.length && j<arr02.length){
              if(arr01[i]<arr02[j]){
                  result.push(arr01[i]);
                  i++;
              }else{
                    result.push(arr02[j]);
                    j++
              }
          }
          //就是数组还没有遍历完,就到底了,其中有一个数组已经结束遍历的,则把后面的进行添加。
          if(i<arr01.length){
               result =  result.concat(arr01.slice(i,arr01.length));
          }
          if(j<arr02.length){
            result =   result.concat(arr02.slice(j,arr02.length));
          }
          return result;
        }
        let arr = [1,4567,867,543,32,123,4236,754,123,234,756,867];
    let result =gb(arr);
    console.log(result);

 拓展延伸题目:.合并二维有序数组成一维有序数组,归并排序的思路;

例子:let arr = [[1,2,35,],[2,3,6,7,8],[1,23,655,999]];

该例子的思路:进行归并排序,将其切割成一个个小数组,然后进行数组的合并。因为最小的数据,是数组,无论是合并之后的,还是合并之前,都是不需要进行数据的判断。

JS实现:

function mergeSort(arr) {
    const len = arr.length
    // 处理边界情况
    if(len <= 1) {
        return arr[0]
    }   
    // 计算分割点
    const mid = Math.floor(len / 2)    
    // 递归分割左子数组,然后合并为有序数组
    const leftArr = mergeSort(arr.slice(0, mid)) 
    // 递归分割右子数组,然后合并为有序数组
    const rightArr = mergeSort(arr.slice(mid,len))  
    // 合并左右两个有序数组
    arr = mergeArr(leftArr, rightArr)  
    // 返回合并后的结果
    return arr
}
  
function mergeArr(arr1, arr2) {  
    // 初始化两个指针,分别指向 arr1 和 arr2
    let i = 0, j = 0   
    // 初始化结果数组
    const res = []    
    // 缓存arr1的长度
    const len1 = arr1.length  
    // 缓存arr2的长度
    const len2 = arr2.length  
    // 合并两个子数组
    while(i < len1 && j < len2) {
        if(arr1[i] < arr2[j]) {
            res.push(arr1[i])
            i++
        } else {
            res.push(arr2[j])
            j++
        }
    }
    // 若其中一个子数组首先被合并完全,则直接拼接另一个子数组的剩余部分
    if(i<len1) {
        return res.concat(arr1.slice(i))
    } else {
        return res.concat(arr2.slice(j))
    }
}

var arr=[[1,2,4],[2,3,7],[3,5,7],[4,5,99]]
// mergeArr(arr)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值