10

快速排序算法

今天大概讲下使用js实现快速排序算法:

快速排序算法的思想类似于二分法,每次都是在数组中选择一个基数(可以是任意一个位置的数,不过一般选择中间的数字或者最左边的数字),每一轮结束后,比该基数小的数都位于该基数的左边,比该基数大的数都位于该基数的右边。然后再分别对基数左边和右边的数组进行相同的操作,直到数组中只有一个元素时,返回该数组。不说了,具体上代码(我取数组最左边的元素作为基数):

var arr=[5,7,2,9,3,8,4,7,1];
// 每次选择最左边的数作为基数
function quickSort(arr){
  if (arr.length<2) { return arr; }
  // 定义左指针
  var left=0;
  // 定义右指针
  var right=arr.length-1;
  //开启每一轮的排序
  while(left<right){
    // 寻找右边比arr[0]小的数的下标
    while(arr[right]>=arr[0] && left<right){
      right=right-1;
    }
    // 寻找左边比arr[0]大的数的下标
    while(arr[left]<=arr[0] && left<right){
      left++;
    }
    //当左边指针与右边指针相遇后,交换arr[0]与当前两个指针所在的元素
    if (right==left) {
      let mid=arr[right];
      arr[right]=arr[0];
      arr[0]=mid;
      break;
    }
    // 当左指针小于右指针的位置,交换两个指针当前位置的元素
    let tem=arr[right];
    arr[right]=arr[left];
    arr[left]=tem;
  }
  //递归实现
  return quickSort(arr.slice(0,left)).concat(arr.slice(left,right+1)).concat(quickSort(arr.slice(right+1)));
}
//对数组进行排序
console.log(quickSort(arr));

问题:为什么如果基数选择数组最左边元素,每次移动必须右指针先移动找到比基数小的数?同理选择右边,要先移动左指针?

回答:解决问题时可以有时候把问题放到极限情况下,这样更加便于我们直观的观察和分析

我们假设如果基数选择数组最左边元素,而我们选择先移动左指针。如果先移动左指针,则此时左指针与右指针相遇,此时交换arr[0]与arr[right],交换后如第二张图所示,本来交换后位于红色7左边的元素应该都小于等于7,但是此时8位于7的左边,明显不符合要求。

clipboard.png


Alisa
243 声望8 粉丝