我這裏考慮的兩個數組均是升序排序,固然降序的兩個數組進行合併算法是相似的。javascript
下面有兩段類似的代碼,第一段除了返回合併後的有序數組還將這兩個有序數組清空了,該算法的思路是始終比較兩個數組的首元素大小,而後將小者 shift 出來 push 到結果數組中去,由於老是會將數組首元素較小的那個移出,故不用改變比較數組的索引值,一直固定爲 0 就好了。最後不要忘記將長度值大於 0 的數組中的元素移出放置到結果數組中。java
/* 清空了原來的兩個有序數組 */
function mergeTwoSortedArr (arr1, arr2) {
var retArr = [];
/* 遍歷比較兩個數組的首元素大小,小者 shift 出來 push 到結果數組中去 */
while (arr1.length > 0 && arr2.length > 0) {
if (arr1[0] < arr2[0]) {
retArr.push(arr1.shift());
} else if (arr1[0] > arr2[0]) {
retArr.push(arr2.shift());
} else {
retArr.push(arr1.shift());
retArr.push(arr2.shift());
}
}
/* 將數組(最多有一個)剩餘元素移出放置到結果數組中 */
while (arr1.length > 0) {
retArr.push(arr1.shift());
}
while (arr2.length > 0) {
retArr.push(arr2.shift());
}
return retArr;
}
// 示例
var arr1 = [2, 3, 5];
var arr2 = [3, 4, 7, 9];
console.log(mergeTwoSortedArr(arr1, arr2)); // [2, 3, 3, 4, 5, 7, 9]
複製代碼
第二段代碼則沒有影響原來的兩個有序數組,經過遍歷比較兩個數組當前元素的大小,小者 push 到結果數組中去,相應數組索引加一,而後再進行循環比較。一樣,最後不要忘記將未遍歷過的數組元素複製到結果數組中。算法
/* 未對原來的兩個有序數組作改動 */
function mergeTwoSortedArr (arr1, arr2) {
var retArr = [];
var len1 = arr1.length;
var len2 = arr2.length;
var i = 0, j = 0;
/* 遍歷比較兩個數組當前元素的大小,小者 push 到結果數組中去,相應數組索引加一 */
while (i < len1 && j < len2) {
if (arr1[i] < arr2[j]) {
retArr.push(arr1[i]);
i++;
} else if(arr1[i] > arr2[j]) {
retArr.push(arr2[j]);
j++;
} else {
retArr.push(arr1[i], arr1[i]);
i++;
j++;
}
}
/* 將數組(最多有一個)剩餘元素 push 到結果數組中 */
for (; i < len1; i++) {
retArr.push(arr1[i]);
}
for (; j < len2; j++) {
retArr.push(arr2[j]);
}
return retArr;
}
// 示例
var arr1 = [2, 3, 5];
var arr2 = [3, 4, 7, 9];
console.log(mergeTwoSortedArr(arr1, arr2)); // [2, 3, 3, 4, 5, 7, 9]
複製代碼
注:上面兩段代碼算法的最後一步最多還要對一個數組進行操做——將其中的元素 push 到結果數組中去,由於以前的循環終止條件就是至少有一個數組已經遍歷結束。數組