从零开始学算法 - 快速排序

快速排序的思路:选一个基准值 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留下的坑

从左向右:[14546, 64, 13, 68, 24, 46, 50, 95],找到第二个比x大的数46,挖出来填5留下的坑

从右向左:[14524, 64, 13, 68, 2446, 50, 95],找到第三个比x小的数24,挖出来填46留下的坑

从左向右:[14524, 64, 13, 68, 6446, 50, 95],找到第三个比x大的数64,挖出来填24留下的坑

从右向左:[1452413, 13, 68, 6446, 50, 95],找到第四个比x小的数13,挖出来填64留下的坑

从左向右:[145241344, 68, 6446, 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);

 

posted @ 2018-10-27 21:15  月亮和电池  阅读(251)  评论(0编辑  收藏  举报