题目
合并二维有序数组,变成一维有序数组,归并排序的思路
let arr = [[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6]]
分析
- 大逻辑是把「子数组」两两合并, 并且排好序的,就算是奇数个子数组,最终也合并为一个。
- 小逻辑是 两个子数组 合并的具体操作。
实现
小逻辑,实现两个子数组的具体合并排序
/*
功能: 将两个有序子数组合并为一个
参数: arr, brr 将要合并的数组
返回: 结果数组
*/
function merge (arr, brr) {
const res = [] // 结果数组
// 其中一个数组长度为0时,就会停止比较排序, 把剩余的元素追加到结果数组尾部
while(arr.length > 0 && brr.length > 0) {
if (arr[0] < brr[0]) {
// 弹出子数组头部元素, 数组长度自然减1, 弹出元素保存至结果数组
res.push( arr.shift() )
} else {
res.push( brr.shift() )
}
}
// 把剩余数组无脑追加到结果中,并返回
return res.concat(arr, brr)
}
大逻辑,实现外层数组两两子数组合并操作
/*
功能: 处理安排哪两个子组数组合并
参数: bigArr 要处理的二维有序数组
返回: 处理好的一维有序数组
算法过程描述
const bigArr = [ 子数组A, 子数组B, 子数组C ]
步骤1:
取出 子数组A, 子数组B bigArr变为 [ 子数组C ]
步骤2:
中间结果数组 = 合并排序(子数组A, 子数组B)
步骤3:
中间结果数组 存到 bigArr bigArr变为 [ 子数组C, 中间结果数组 ]
重复之前操作, 合并两个数组
bigArr 变成 [ 最终结果数组 ]
*/
function arrayFlat (bigArr) {
if (bigArr.length === 0) return [] // 数组长度为0, 则直接返回空数组
// 数组长度大于1时循环,等于1时结束
while(bigArr.length > 1) {
let sub1 = bigArr.shift() // 取第0个子数组, 长度减1
let sub2 = bigArr.shift() // 取第1个子数组, 长度减1
let tmpArr = merge(sub1, sub2) // 合并两个子数组为中间临时数组
bigArr.push(tmpArr) // 中间临时数组压入原来的大数组中
}
// 数组长度等于1时,返回第一个,也是唯一的元素,即排好序的数组
return bigArr[0]
}
测试和结果
let xxx = [[2,5,6],[7,9,10],[1,4,8],[3,13],[12,14]]
let result = arrayFlat( xxx )
console.log( result )
也在学习前端的朋友, 可以一起讨论. 个人微信 h2o_9527 / QQ群 929330787