面试_算法_快速排序

110 阅读2分钟

基本思想

选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分。其中左半部分都比基准数小,右半部分都比基准数大。这样经过一次排序就能确定一个基准数的最终位置。递归地对左右两部分做同样的操作,每一次操作都能确定一个元素的位置,直到所有元素的位置都被确定,排序完成。



Partition函数

快排最重要的就是Partition函数,网上的版本有很多,虽说结果一致但步骤不尽相同。下面的是我最喜欢的一种方式:


在每一趟中:

  • 首元素作为基准值

  • 左指针初始时指向基准值,但循环刚开始时有一个++i,说明其实是从首元素的下一个位置开始比较的

  • 右指针初始时指向数组最后一个元素的下一个位置,但循环刚开始时有一个--j,说明其实是从尾元素开始比较的

  • 先向后移动左指针,直至找到一个不小于基准值的元素,停下来(先不与任何元素交换

  • 再向前移动右指针,直至找到一个小于基准值的元素,停下来(先不与任何元素交换

  • 检查当前两个指针是否重合或者早已穿过彼此,若没有,则交换两个指针所指向的元素的位置(指针不动),然后继续移动两个指针(回到第4,5步);若是,则break跳出循环,此时右指针所指向的元素就是想要的分裂点**,**将该分裂点与基准值交换位置,并返回原分裂点位置 j 。(只能是右指针,不能是左指针)


实现代码如下:

public static int Patition(int[] arr, int low, int high) {
    int i = low, j = high + 1;   // 可以"high+1" 是因为后面用到了--j
    int x = arr[low];  // 基准值
    while (true) {
        while (arr[++i] <= x && i < high) ;  // 从左往右找大于基准值x的数的位置i,找不到的话i==r
        while (arr[--j] > x && j>low) ;  // 从右往左找小于等于基准值x的数的位置i,找不到的话j==p
        if (i >= j)
            break;  
        swap(arr, i, j);   
    }
    swap(arr, low, j); //因为最开始用到了++i,所以基准值至始至终都没有参与换位,所以可以直接拿low来交换
    return j;  
}

全部代码:

import java.util.ArrayList;
import java.util.Arrays;

public class Solution {
    public static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

    public static int Patition(int[] arr, int low, int high) {
        int i = low, j = high + 1;  
        int x = arr[low];
        while (true) {
            while (arr[++i] <= x && i < high) ;
            while (arr[--j] > x && j > low) ;
            if (i >= j)
                break;
            swap(arr, i, j);
        }
        swap(arr, low, j);   
        return j;
    }

    public static void QuickSort(int[] arr, int low, int high) {
        if (low < high) {
            int pivot = Patition(arr, low, high);
            QuickSort(arr, low, pivot - 1);
            QuickSort(arr, pivot + 1, high);
        }
    }

    public static void main(String[] args) {
        int[] arr = {6,7,5,2,5,8};
        int len = arr.length;
        QuickSort(arr, 0, len - 1);
        System.out.println(Arrays.toString(arr));
    }
}



示例





www.icourse163.org/learn/QDU-1…