快速排序实现(Java)

文字描述:

1、每一轮排序选择一个基准点(pivot)进行分区

(1)让小于基准点的元素的进入一个分区,大于基准点的元素进入另一个分区

(2)当分区完成后时,基准点元素的位置就是其最终位置

2、在子分区内重复以上过程,直至子分区元素个数少于等于 1,这体现的是分而治之的思想(divide-and-conquer)


实现方式:

1、单边循环快排

(1)选择最右元素作为基准点元素

(2)j 指针负责找到比基准点小的元素,一旦找到则与 i 进行交换

(3)i 指针维护小于基准点元素的边界,也就是每次交换的目标索引

(4)最后基准点与 i 交换,i 即为分区位置

2、双边循环快排

(1)选择最左元素作为基准点元素

(2)j 指针负责从右向左找比基准点小的元素,i 指针负责从左向右找比基准点大的元素,一旦找到二者交换,直至 i,j 相交

(3)最后基准点与 i(此时 i 与 j 相等)交换,i 即为分区位置


代码

单边循环

public class QuickSortDemo {
    
    

    public static void main(String[] args) {
    
    
        int[] array = {
    
    5, 9, 7, 4, 1, 3, 2, 8};

        quickSort(array);
        System.out.println(Arrays.toString(array));
    }

    /**
     * 快排单边循环
     * 以最右边的元素为基准值
     * i 负责维护分区的边界,j 负责从左至右找比基准值大的
     * 与 i 交换,最后 i 所在的位置就是基准值要去的位置
     * 然后一直分区重复步骤
     * 结束条件:分区里的元素 <= 1
     */
    public static void quickSort(int[] array, int l, int h) {
    
    
        if (l >= h) {
    
    
            return ;
        }
        // 以分区最右边的元素为基准点
        int pv = array[h];
        // i 维护分区的边界,i 左边比基准值小,右边比基准值大
        int i = l;

        for (int j = l; j < h; j++) {
    
    
            if (array[j] < pv) {
    
    
                if (i != j) {
    
    
                    swap(array, i, j);
                }
                i++;
            }
        }
        // i 的位置就是基准点要去的位置
        if (i != h) {
    
    
            swap(array, i, h);
        }

        // 进行递归
        quickSort(array, l, i - 1);
        quickSort(array, i + 1, h);
    }

    public static void quickSort(int[] array) {
    
    
        quickSort(array, 0, array.length - 1);
    }

    /**
     * 交换数组中的两个元素
     */
    public static void swap(int[] array, int i, int j) {
    
    
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

双边循环

/**
 * 快排双边循环
 * 以最左边的元素为基准值
 * i 从左至右找比基准值大的
 * j 从左至右找比基准值小的
 * i, j 交换
 * 最后 i 或 j 就是基准值要去的位置
 */
public static void quickSort(int[] array, int l, int h) {
    
    
    if (l >= h) {
    
    
        return ;
    }
    // 以最左边的元素为基准值
    int pv = array[l];
    int i = l;
    int j = h;

    while (i < j) {
    
    
        // 先 j 后 i,位置不能颠倒
        while (i < j && array[j] > pv) {
    
    
            j--;
        }

        // array[i] <= pv,第一次 i == l 的,会把基准值交换走
        while (i < j && array[i] <= pv) {
    
    
            i++;
        }

        swap(array, i, j);
    }
    // 交换元素
    swap(array, i, l);

    quickSort1(array, l, i - 1);
    quickSort1(array, i + 1, h);
}

猜你喜欢

转载自blog.csdn.net/m0_52462015/article/details/120695967