Merge Sort : 歸併排序,把一個大問題分解成若干相同的小問題,解決小問題後,合併小問題結果,最終把大問題解決. 例如要排序數組 originArr = [2, 5, 3, 8, 9, 6, 3, 4, 2] 先把問題分解爲排序 leftArr = [2, 5, 3, 8, 9] 和 rightArr = [6, 3, 4, 2]兩個小數組,而後合併leftArr和rightArr,當排序leftArr的時候發現問題仍是太複雜, 再把leftArr分解爲 leftArr1 = [2, 5, 3] 和 rightArr1 = [8, 9] ...以此遞歸調用,直到 leftArrN = [2]...數組
//分治法排序 var originArr = [2, 5, 3, 8, 9, 6, 3, 4, 2] let startTime = new Date().valueOf(); console.info("原始數組:", originArr) function mergeSort(arr, from, to) { //尋找合適的分割點 let mid = parseInt((to + from) / 2); if (to > from) { //若是 to!= from 說明問題仍是太複雜,遞歸調用分解問題 mergeSort(arr, from, mid); mergeSort(arr, (mid+1), to); //合併左邊已經排好序的,和右邊已經排好序的 merge(arr, from, mid, to); } } function merge(arr, from, mid, to) { let leftArr = []; let rightArr = []; //先把arr左邊排好序的部分扔到臨時數組leftArr中 for(let i=from; i<= mid; i++) { leftArr.push(arr[i]); } //先把arr右邊排好序的部分扔到臨時數組rightArr中 for(let j=mid+1; j<= to; j++) { rightArr.push(arr[j]); } //合併規則是,每次比較左邊和右邊最上面的值,把比較小的扔到arr[n]中,當左邊沒有了或者右邊沒有了,則把對應的另一個數組剩下的值依次放入到arr[n]中 let i=0, j=0; for(let n=from; n<= to; n++) { //左邊數組沒有值了,把右邊數組剩下的值依次扔到arr[n]中 if (i>= leftArr.length) { arr[n] = rightArr[j]; j++; continue; } //右邊數組沒有值了,把左邊數組剩下的值依次扔到arr[n]中 if (j >= rightArr.length) { arr[n] = leftArr[i]; i++; continue; } //若是左邊右邊數組都有值,把二者比較小的那個扔到arr[n]中 if (leftArr[i] > rightArr[j]) { arr[n] = rightArr[j]; j++; } else { arr[n] = leftArr[i]; i++; } } // console.info(`分隔點:${from}, ${mid}, ${to}, 合併完成後:`, arr) } mergeSort(originArr, 0, originArr.length-1); console.info("最終排序結果:", originArr) let endDate = new Date().valueOf() console.info("花費時間:", endDate - startTime) 打印結果: 原始數組: [ 2, 5, 3, 8, 9, 6, 3, 4, 2 ] 最終排序結果: [ 2, 2, 3, 3, 4, 5, 6, 8, 9 ] 花費時間: 36
歸併排序的時間複雜度爲nlogncode