https://jsbin.com/jukakutoxa/4/edit?js,console
归纳公式
转公式为代码
实现merge函数
人类思维
比较两边数组的第一个,谁小就把谁放入新的数组内,相应的index要+1。
操作次数:i+j
https://jsbin.com/yakokipuwa/1/edit?js,console
function merge(array1, array2){const len1 = array1.length;const len2 = array2.length;const result = [];let i = 0, j = 0;while(i < len1 || j < len2) {if (i >= len1) { result.push(array2[j]); j += 1;} else if(j >= len2) { result.push(array1[i]); i += 1;} else if (array1[i] > array2[j]) { result.push(array2[j]); j += 1;} else { result.push(array1[i]); i += 1; }}return result;}const array1 = [1, 4, 6];const array2 = [2, 3, 9];console.log(merge(array1, array2))console.log(merge([], array2))console.log(merge([], []))
优化
https://jsbin.com/xavabirile/edit?js,console
不生成和复制新的对象,在原对象的基础上进行优化。
// 就地优化function merge(array, middle){let i = 0, j = middle;const len = array.length;while(i < middle && j < len) {w = 0;while(array[i] <= array[j]) { i += 1; }while(array[i] > array[j]) { j += 1; w += 1; }if (w > 0) {const split = array.splice(j - middle + 1, w);array.splice(i, 0, ...split);}}return array;}// 0 1 2 3 4 5const array = [1, 4, 6, 2, 3, 9];console.log(merge(array, 3))
数学思维
操作次数:无法计算,由于slice和concat的实现方式位置
function merge2(a, b) {if (a.length === 0) return b;if (b.length === 0) return a;return a[0] > b[0]? [b[0]].concat(merge2(a, b.slice(1))): [a[0]].concat(merge2(a.slice(1), b))}
实现sort函数
https://jsbin.com/yakokipuwa/2/edit?js,console
操作次数:每次sort会slice两次,内存翻倍*4,每次sort会压栈3次,压很多次
function sort(array) {const len = array.length;if (len === 1) return array;if (len === 2) return array[0] < array[1] ? array : [array[1], array[0]];const middleIndex = Math.floor(len / 2);const left = array.slice(0, middleIndex);const right = array.slice(middleIndex);return merge(sort(left), sort(right));}
优化
https://jsbin.com/fagibubiko/edit?js,console
// 就地优化function merge(array, start, middle, end) {let i = start, j = middle;const len = end;while(i < middle && j < len) {w = 0;while(array[i] <= array[j] && i < middle) { i += 1;}while(array[i] > array[j] && j < end) {j += 1;w += 1;middle += w;}if (w > 0) { const split = array.splice(j - w, w);array.splice(i, 0, ...split); }}return array;}const sort = (array) => sortInPlace(array, 0, array.length)function sortInPlace(array, start, end) {if (end - start === 1) return array;const middle = Math.floor((start + end) / 2);sortInPlace(array, start, middle)sortInPlace(array, middle, end);merge(array, start, middle, end);return array;}console.log(sort([1,34,39, 7,10,5, 3, 1]))console.log(sort([1,34,7,9090,39,10,5]))
自底向上的思考方式
https://jsbin.com/fefedezeve/edit?js,console
// 就地优化function merge(array, start, middle, end) {if (start > array.length) {start = array.length - 1}if (middle > array.length) {middle = array.length}if (end > array.length) {end = array.length}let i = start, j = middle;const len = end;console.log(`merge循环 array ${array} start ${start} middle ${middle} end ${end}`)while(i < middle && j < len) {w = 0;console.log(`开始循环`);console.log('i vakye', array[i], 'jvalue', array[j])while(array[i] <= array[j] && i < middle) {i += 1;}while(array[i] > array[j] && j < end) {j += 1;w += 1;middle += w;}console.log(`i=${i} j=${j} w=${w}`)if (w > 0) {const split = array.splice(j - w, w);console.log(`split ${split}`);array.splice(i, 0, ...split);console.log(`array ${array}`);}}console.log(`merge结果 ${array}`)return array;}// 0 1 2 3 4 5// const array = [1, 4, 6, 2, 3, 9];// console.log(merge(array, 0, 3, array.length))// const array2 = [1, 4, 6, 7, 1, 3, 9, 10, 99];// console.log(merge(array2, 0, 4, array2.length))const sort = (array) => {const odd = array.length % 2 === 1;const len = !odd ? array.length : array.length + 1;// const len = array.length;for(let size = 2; size <= len; size *= 2) {console.log(`---------------外层 size ${size}`)for(let i = 0; i < len; i += size) {console.log(`内层 i ${i}`)let start = i, end = start + size, middle = Math.floor((start + end)/2);// if (end > array.length) end = array.length;merge(array, start, middle, end);}}if (odd) merge(array, 0, array.length - 1, array.length);console.log('===================')return array;}console.log(sort([1,34,39, 7,10,5, 3, 1]))console.log(sort([1,34,7,9090,39,10,5]))console.log(sort([1,34,7,9090,39, 5, 1, 10,5]))
