从零开始学算法 - 快速排序
快速排序的思路:选一个基准值 current,把比它大的放在它右边,比它小的放在它左边,递归直到排序完成。
用一个10个数字的数组,解释一下快速排序的过程:
第一趟:
原始数组:[44, 95, 46, 64, 13, 68, 24, 5, 50, 14],给三个参数 i=0,j=len-1,x
挖一号坑:[44, 95, 46, 64, 13, 68, 24, 5, 50, 14],把第一个数44挖出来,x = arr[0] = 44
从右向左:[14, 95, 46, 64, 13, 68, 24, 5, 50, 14],找到第一个比x小的数14,挖出来填44留下的坑
从左向右:[14, 95, 46, 64, 13, 68, 24, 5, 50, 95],找到第一个比x大的数95,挖出来填14留下的坑
从右向左:[14, 5, 46, 64, 13, 68, 24, 5, 50, 95],找到第二个比x小的数5,挖出来填95留下的坑
从左向右:[14, 5, 46, 64, 13, 68, 24, 46, 50, 95],找到第二个比x大的数46,挖出来填5留下的坑
从右向左:[14, 5, 24, 64, 13, 68, 24, 46, 50, 95],找到第三个比x小的数24,挖出来填46留下的坑
从左向右:[14, 5, 24, 64, 13, 68, 64, 46, 50, 95],找到第三个比x大的数64,挖出来填24留下的坑
从右向左:[14, 5, 24, 13, 13, 68, 64, 46, 50, 95],找到第四个比x小的数13,挖出来填64留下的坑
从左向右:[14, 5, 24, 13, 44, 68, 64, 46, 50, 95],两侧下标相遇,i=j=4,把x拿过来填在这里
这时,以44为分界,左侧的数字全部比它小,右侧的数字全部比它大。
继续,以44为分界,将数组分成:[14, 5, 24, 13]和[68, 64, 46, 50, 95]两部分,循环上述过程,知道完成排序。
将上述过程翻译成代码:
function quickSort(arr,left,right){ //如果left和right没传,就代表是第一次调用,给个默认值 var left = typeof left == "number" ? left:0; var right = typeof right == "number" ? right:arr.length-1; if (left < right){ var i = left; var j = right; var x = arr[left]; while (i < j){ //从右向左找比x小的数 while(i<j && arr[j]>=x){ j--; } //把找到的arr[j]挖出来,给arr[i],同时i++ if(i<j){ arr[i] = arr[j]; i++; } //从左向右找比x大的数 while(i<j && arr[i]<=x){ i++; } //把找到的arr[i]挖出来,给刚才空出来的arr[j],同时j-- if(i < j){ arr[j] = arr[i]; j--; } } //上述过程在i和j相遇时结束,此时的arr[i]空了出来,把x填在这儿 arr[i] = x; //将数组以i为分界,分成两部分,再循环调用 quickSort(arr, left, i - 1); quickSort(arr, i + 1, right); } } //调用方法 var array=[]; for(var i=0;i<10;i++){ array[i] = Math.floor(Math.random()*100); } quickSort(array);