快排 原理/解释/实现

122 阅读1分钟

原理

  • 任取一个元素(如:第一个)为中心值;
  • 比它小的元素放前面,比它大的元素放后面;
  • 形成两个子表,左边的表都比中心元素小,右边的子表都大;
  • 子表分别重复以上操作,选取中心值,分左右子表
  • 直到子表中只剩一个元素

形成左右子表

  • 在数组内,原地交换位置,左边小,右边大,中心值arr[0]
  • 需要两个指针,left指向头,从左至右自增;right指向尾,右至左自减
  • arr[right] > 中心值,位置不用变;right-- ; arr[right]< 中心值,right不自减,这时arr[right]需要放到左边/前面
  • arr[left] < 中心值,位置不用变;left++ ; arr[left]> 中心值,left不自加,这时arr[left]需要放到右边/后面
  • 把需要换位置的 arr[left],arr[right]位置对调;再继续比较
  • left,right重合时,left是属于左子表的,arr[0],arr[left]互换位置,把中心值放到分界处

代码实现

// 递归分出左右子表
function sort(arr, left, right ){
        if(left < right){
           let index = patition(arr, left, right);
           sort(arr, left, index-1);
           sort(arr, index+1, right);
        }
     }
     
// 比大小,找出中心位置
     function patition(arr, left, right){
        console.log(arr[left],left,right)
        let p = arr[left];// 中心值
        let i = left;
        let j = right;
        while(i < j){
            // 从右至左递减,大于p位置不动,j--; 小于p,j停下,等待交换
            while(arr[j] >= p && i < j){
                j--;
            }
            while(arr[i] <=p && i < j){
                i++;
            }
            swap(arr, i, j);
        }
        // 把中心值放到分界处
        swap(arr, left, i);
        return i;
     }
  
// 交换位置
     function swap(arr,i,j){
        let t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
     }
     const arr = [49,46,24,56,82,45,12,21,88,55];
     sort(arr,0,arr.length-1);
     console.log(arr)