快速排序和归并排序是典型的分治算法。
code:快速排序
<!doctype html> <html> <head> <meta charset="utf-8"> <title>快速,归并</title> </head> <body> <div id="log"></div> <script> var data = [],num = 1000; for(var i = 0;i<num;i++){ data.push(Math.floor(Math.random()*num)) } console.time('quick2') var newData = quick2(data); console.timeEnd('quick2') data = []; for(var i = 0;i<num;i++){ data.push(Math.floor(Math.random()*num)) } console.time('quickSort') var newData = quickSort(data); console.timeEnd('quickSort') function quick2(data,base){ if(data.length < 2 ){return data;} var d1=[],d2=[],base = base||data.shift(); for(var j = 0 ;j < data.length;j++){ if(data[j]>base){ d1.push(data[j]); }else{ d2.push(data[j]); } } return [].concat(quick2(d1)).concat(base).concat(quick2(d2)); } function quickSort(array) { function sort(prev, numsize) { var nonius = prev; var j = numsize - 1; var flag = array[prev]; if ((numsize - prev) > 1) { while (nonius < j) { for (; nonius < j; j--) { if (array[j] < flag) { array[nonius++] = array[j]; //a[i] = a[j]; i += 1; break; }; } for (; nonius < j; nonius++) { if (array[nonius] > flag) { array[j--] = array[nonius]; break; } } } array[nonius] = flag; sort(prev, nonius); sort(nonius + 1, numsize); } } sort(0, array.length); return array; } </script> </body> </html>
quick2 是我自己根据分治的意思写的,写完之后去网上查,发现网上的都是挖坑算的,quickSort是网上找的,一开始运行很慢,后来改了处关键地方就快了,
计较结果上看,quickSort优势还是很明显的,可能是我用临时变量太多引起的。
可能利用了cancat的便利性(据说数组的concat方法比直接for循环push要慢)。
接下来是归并,我自己尝试写的
function merge(data){ if(data.length === 1){ return data; } var y = data.length%2; var s = y?(data.length-1)/2:data.length/2; var d1 = merge(data.slice(0,s)); var d2 = merge(data.slice(s,data.length)); var i=0; var j=0; var d3=[]; while(i<d1.length || j<d2.length){ if(!d1[i]){ d3.push(d2[j++]); }else{ if(!d2[j]){ d3.push(d1[i++]); }else{ if(d2[j]<d1[i]){ d3.push(d2[j++]); }else{ d3.push(d1[i++]); } } } } return d3; }
但是明显比快速排序慢一些,我去百度上找了一段
function merge1(left, right) { var result = []; while (left.length > 0 && right.length > 0) { if (left[0] < right[0]) { /*shift()方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。*/ result.push(left.shift()); } else { result.push(right.shift()); } } return result.concat(left).concat(right); } function mergeSort(items) { if (items.length == 1) { return items; } var middle = Math.floor(items.length / 2), left = items.slice(0, middle), right = items.slice(middle); return merge1(mergeSort(left), mergeSort(right)); }
明显人家的归并这一步干净利索,让我汗颜啊
赶紧copy过来。
尴尬的是竟然变慢了三分之一。。。
比快速排序慢的原因应该还是临时变量太多
练习:
输入
首先是解析
<div id='wis'></div> <script src="jquery.js"></script> <script> function decompress(str){ var docompressed = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]],ary = str.split(''),it = 0; function de(y,x,size){ var head = ary[it++]; console.log(it + ' & ' + head + '->y: ' + y + ', x: ' + x + ', s: ' + size); if(head == 'b' || head == 'w'){ for(var i = 0;i<size;i++){ for(var j = 0;j<size;j++){ docompressed[i+y][j+x] = head; } } console.log(docompressed); }else{ var half = size/2; de(y,x,half); de(y,x+half,half); de(y+ half,x,half); de(y + half,x +half,half); } } de(0,0,16); return docompressed; } var data = decompress('xxwwwbxwxwbbbwwxxxwwbbbwwwwbb'), width = $(window).width(); for( var m = 0; m< data.length;m++){ var d = $('<div style="100%;float:left">'); for(var n=0;n<data[m].length;n++){ d.append($('<div >').css('width','20px').css('height','20px').css('background-color',data[m][n] === 'w'?'#c1c1c1':'black').css('float','left')); } $(wis).append(d); }
</script>
然后是反转数组,再次压缩。。
还是学习他的第二种方案吧
完整的代码如下:
<div id='wis'></div> <script src="jquery.js"></script> <script> function decompress(str){ var docompressed = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]],ary = str.split(''),it = 0; function de(y,x,size){ var head = ary[it++]; console.log(it + ' & ' + head + '->y: ' + y + ', x: ' + x + ', s: ' + size); if(head == 'b' || head == 'w'){ for(var i = 0;i<size;i++){ for(var j = 0;j<size;j++){ docompressed[i+y][j+x] = head; } } console.log(docompressed); }else{ var half = size/2; de(y,x,half); de(y,x+half,half); de(y+ half,x,half); de(y + half,x +half,half); } } de(0,0,16); return docompressed; } function recerse(str){ var ary = str.split(''),it=0; function op(){ var head = ary[it++]; if(head == 'b' || head == 'w'){ return head; } var leftUp = op(it); var rightUp = op(it); var leftDown = op(it); var rightDown = op(it); return 'x' + leftDown + rightDown + leftUp + rightUp; } return op(); } function show(data){ for( var m = 0; m< data.length;m++){ var d = $('<div style="100%;float:left">'); for(var n=0;n<data[m].length;n++){ d.append($('<div >').css('width','20px').css('height','20px').css('background-color',data[m][n] === 'w'?'#c1c1c1':'black').css('float','left')); } $(wis).append(d); } $(wis).append($('<div style="100%;float:left;border-bottom:1px solid red;">')); } var str = 'xxwwwbxwxwbbbwwxxxwwbbbwwwwbb'; var data = decompress(str); show(data); var data2 = decompress(recerse(str)); show(data2); </script>