数组排序with javascript

来源:互联网 发布:批量加微信好友软件 编辑:程序博客网 时间:2024/06/02 12:59

尝试了下用javascript练习排序(博客园的代码提示略坑)还是放这里吧。

function bubbleSort(arr){console.log("冒泡排序:");var len = arr.length;for(var i=0; i<len-1;i++){for(var j=0; j<len-i-1; j++){if(arr[j]>arr[j+1]){var temp = arr[j+1];arr[j+1] = arr[j];arr[j] = temp;}}}return arr;}function chooseSort(arr){console.log("选择排序:");var len = arr.length;for(var i=0; i<len-1;i++){for(var j=i+1; j<len; j++){if(arr[i]>arr[j]){    var temp = arr[j];arr[j] = arr[i];arr[i] = temp;}}}return arr;}function quickSort(arr, left, right){if(undefined===left){console.log("快速排序改实参版:");left=0;}if(undefined===right){right = arr.length-1;}if(left>right){return;}//移动左右索引变量var i = left;var j = right;var midKey = arr[left];while(i<j){while(i<j&&midKey<=arr[j]){j--;}while(i<j&&midKey>=arr[i]){i++;}if(i<j){var temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}//交换中间数与中轴数arr[left] = arr[i];arr[i] = midKey;//递归左右,分治思想quickSort(arr, left, i-1);quickSort(arr, i+1, right);return arr;}function quickSortArr(arr){if(arr.length==1){return arr;}if(arr.length==0){return [];}var left = [],right = [];var povit = arr[0];for(var i=1;i<arr.length;i++){if(arr[i]<=povit){left.push(arr[i]);}else{right.push(arr[i]);}}var re = quickSortArr(left).concat([povit],quickSortArr(right));return re;}function timeIt(fn, arr){var start = new Date().getTime();arr = fn(arr);var end = new Date().getTime();console.log("cost(ms):"+(end-start)+" result:"+arr[0]+ " " + arr[1] +" "+arr[2]+"..."+arr[arr.length-1]);}function callArraySort(arr){console.log("Array内置排序:");//console.log(arr[0]);return Array.prototype.sort.call(arr, compareByArray);//console.log(b[0]);//console.log(b.length);}function compareByArray(a,b){var i = parseInt(a);var j = parseInt(b);return i-j;}function heapSort(arr){function maxHeapify(arr, index, len){var left = getLeft(index);var right = getRight(index);var largest;if(left<len&&arr[left]>arr[index]){largest = left;}else{largest = index;}if(right<len&&arr[right]>arr[largest]){largest = right;}if(largest!=index){swapElement(arr, largest, index);maxHeapify(arr, largest, len); // 如果改变了位置,递归改变的子树调整}}function swapElement(arr,index0, index1){var temp = arr[index0];arr[index0] = arr[index1];arr[index1] = temp;}function getLeft(eleIndex){return 2*eleIndex+1;}function getRight(eleIndex){return 2*(eleIndex+1);}if(arr.length<=1){return arr;}var len = arr.length;for(var i=len/2+1;i>=0;--i){maxHeapify(arr, i, len);}for(var i=len-1;i>=1;--i){swapElement(arr, 0, i);maxHeapify(arr, 0, --len);}return arr;}var a = [2,5,3,2,2,8,5,9,4,6,3,1,3,7];//console.log(bubbleSort(a));timeIt(bubbleSort, a);a = [2,5,3,2,2,8,5,9,4,6,3,1,3,7];timeIt(chooseSort, a);//console.log(chooseSort(a));a = [2,5,3,2,2,8,5,9,4,6,3,1,3,7];timeIt(quickSort, a);//console.log(quickSort(a));a = [2,5,3,2,2,8,5,9,4,6,3,1,3,7];console.log("快速排序不改原参数版:");timeIt(quickSortArr, a);a = [2,5,3,2,2,8,5,9,4,6,3,1,3,7];timeIt(callArraySort, a);a = [2,5,3,2,2,8,5,9,4,6,3,1,3,7];console.log("堆排序:");timeIt(heapSort, a);var randArr = [];for(var i=0;i<10000; i++){randArr[i] = Math.floor(Math.random()*100000);} a = randArr.slice();timeIt(bubbleSort, a)a = randArr.slice();timeIt(chooseSort, a);//console.log(chooseSort(a));a = randArr.slice();timeIt(quickSort, a);a = randArr.slice();console.log("快速排序不改原参数版:");timeIt(quickSortArr, a);a = randArr.slice();timeIt(callArraySort, a);a = randArr.slice();console.log("堆排序:");timeIt(heapSort, a);
冒泡跟选择以前容易混淆,是因为不明白怎样叫冒泡,实际上,冒泡就是对整个序列,进行一趟前后元素两两比较的形式,大的数后移(或者小的),这样达到一趟实现了把大的数(或者小的数)移到了尾部,那整一个序列看成尾部朝上,往后一趟序列,从头开始一直到倒数第n个数进行两两比较,犹如关键元素(最大值或者最小值)往上冒泡的样子 ,因此叫冒泡。

而选择排序,则是对序列的每个数,从头开始,针对该位置与剩下的数进行比较, 如果有出现大于(小于)该位置的数,则交换位置,这样每一趟下来,就能确定固定位置该放置的数。 //这个解释感觉跟选择没多大关联,姑且当做是选择位置吧。

那么快速排序,就是直接用效率命名了。为什么快呢?看代码实现 ,while里面还有while,还有递归,感觉不快的样子,关于时间复杂度的问题,我还没嚼透。


快排思想是分而治之,既然一个分散的序列,假设通过比较某个值,分别将大于和小于该数的分到一边,就成了两部分,然后同样的道理,各部分再按切分大小方法再细分成两部分……以此推下去,直到变成了最小的部分就是三个数,a<b<c,这个时候各个细小部分组合起来,明显就是一个排序好的序列了。


运行结果,感受下:



0 0
原创粉丝点击