归并排序

103 阅读1分钟

思路

将已有的俩个有序的子数组合并,得到完全有序的数组【二路归并】

先拆分,拆成只有一个元素的时候,拆完后开始依次排序,合并

「推导:」

25743698
//先执行sort,拆分
2574,3698
25743698
2,5,7,4,3,6,9,8
开始俩俩进merge开始合并
25 47 36 89
2475 3689
234567892547这段举例
l:[2,5] r:[4,7] n:[]
2 < 4  l:[5] r:[4,7] n:[2]
5 > 4  l:[5] r:[7] n:[2,4]
5 < 7 l:[] r:[7] n:[2,4,5] 合并:[2,4,5,7]

「代码」

function sortArray(nums: number[]) {
 nums = sort(nums)
 return nums

 function sort(nums: number[]): number[] {
   let len = nums.length;
   if (len === 1) {
     return nums;
   }
   //拆分
   const mid = len/2;
   const left = nums.slice(0, mid);
   const right = nums.slice(mid);
   //当sort拆分完成之后依次执行merge
   return merge(sort(left),sort(right));
 }

 function merge(left: number[],right:number[]): number[] {
   const newArr:number[] = []
   //其中一个为0,另一个数组绝对比newArr大,合并上去
   while(left.length > 0 && right.length > 0){
     //类似于快排思路,循环找出小的,一旦卡住就从大的开始动
     if(left[0] < right[0]){
       newArr.push(left.shift() as number)
     }else{
       newArr.push(right.shift() as number)
     }
   }
   return newArr.concat(left).concat(right);
 }
}

时间复杂度O(nlogN) 空间复杂O(n) 稳定