Java--快速排序

        快速排序是对冒泡排序的改进,可以分单向扫描法和双向扫描法两种。

        首先看单向扫描的快速排序:

1. 选定数组的一个元素作为“主元”(也可以称为基准或枢轴)。之后扫描一趟数组,将小于或等于主元的元素放在主元的左边,大于主元的元素放在主元的右边。具体做法是:

        a.选定数组的第一个元素作为主元。

        b.定义左指针lp和右指针rp,用数组下标赋值。其中rp右侧的数据都大于主元。初始时,lp指向数组的第二个元素,rp指向数组的最后一个元素。

        c.第一趟的扫描流程为:在左指针下标小于或等于右指针下标的条件下进行循环,比较是否 左指针所指元素小于或等于主元,如果是,左指针右移一位;否则,交换两指针所指元素,并将 右指针左移一位。

        交换过程如下图所示(左指针lp所指元素大于主元,与右指针rp所指元素交换,且右指针左移一位):

        d.循环继续,比较得到此时左指针所指元素小于主元(1 < 4),左指针右移一位。

        e.再次比较得到左指针所指元素不小于主元(6 > 4),交换两指针所指元素,并将右指针左移一位。

        交换过程如下图所示:

        f.再次比较[lp]小于主元(2 < 4), 左指针右移一位。

        g.[lp]不小于主元(7 > 4),交换两指针所指元素,并将右指针左移一位。

         此时,lp == rp,仍满足左指针小于或等于右指针的条件,继续比较[lp]小于主元(3 < 4),那么左指针右移一位,此时lp > rp。

        循环结束,rp右侧的数据都大于主元,且rp所指元素小于主元,此时交换rp所指元素与主元。至此第一趟快速排序完成。

2. 此时,数组以主元为界,分为两部分,分别对两部分递归实现快速排序,即再次选取新主元进行排序。

图片描述

3. 上述递归结束的条件是:子数组中只有1个元素或0个元素。

图片描述

单向扫描的快速排序图示

        单向扫描的快速排序代码:

public class QuickSort {
    // 递归实现单向扫描的快速排序
    public void quickSort(int[] arr, int l, int r) {
        if (l < r) {
            // 进行一躺快速排序,取当前主元作为边界
            int q = pv(arr, l, r);
            // 分别扫描排序边界两侧
            quickSort(arr, l, q - 1);
            quickSort(arr, q + 1, r);
        }
    }
    
    // 实现数组的一趟单向扫描的快速排序。从l扫描到r,返回当前主元位置
    public int pv(int[] arr, int l, int r) {
        // 主元p
        int p = arr[l];
        // 扫描指针:左指针lp,右指针rp
        int lp = l + 1;
        int rp = r;
        while (lp <= rp) {
            // 如果左指针所指的数小于等于主元,左指针右移一位
            if (arr[lp] <= p) 
                lp++;
            else { // 如果大于主元,交换左右指针的数据,右指针左移一位
                swap(arr, lp, rp);
                rp--;
            }
        }
        swap(arr, l, rp);// 交换主元和指针所指的数据
        return rp;
    }

    // 实现数组中两个元素的交换
    public void swap(int[] arr, int index1, int index2) {
        int temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }
}

        再就是双向扫描的快速排序:

1. 和单向扫描法一样,双向扫描法也是选定数组的一个元素为主元,然后对于主元之外的元素,从左右两侧同时扫描。小于或等于主元的元素放在主元的左边,大于主元的元素放在主元的右边。具体做法是:

        left向右扫描的过程中,如果left所指元素小于或等于主元,则left右移一位,否则停止移动;right向左扫描的过程中,如果right所指元素大于主元成立,则right左移一位,否则停止移动。当left和right都停止移动时,如果left ≤ right,则交换两指针所指元素。

        a.选定数组的第一个元素为主元。

        b.除主元之外的元素,选定数组的第二个元素为左侧left,数组的最后一个元素为右侧right,并且同时向右 / 左扫描。

图片描述

         c.left向右扫描(移动),发现当前所指元素不小于主元(5 > 4),停止移动;right向左扫描,发现当前所指元素不大于主元(1 < 4),停止移动。此时左右两侧都停止移动,并交换两侧所指元素。

图片描述

图片描述

        d.重复c的步骤。再对[2]和[5]、[3]和[4]交换。

图片描述

        e.此时left ≤ right,left所指元素小于主元,right所指元素大于主元,所以left右移,right左移。

图片描述

        f.当前left > right,循环终止,交换right所指元素与主元。 

图片描述

        至此第一趟排序完成。 

2. 再用递归,将此时主元(right)左侧和右侧的子数组视为两个待排序的数组,再次进行排序。

         双向扫描的快速排序代码:

public class DoubleQuickSort {
    // 递归实现双向扫描的快速排序
    public void quickSort(int[] arr, int l, int r) {
        if (l < r) {
            int q = pv2(arr, l, r);
            quickSort(arr, l, q - 1);
            quickSort(arr, q + 1, r);
        }
    }

    // 一趟双向扫描的快速排序,返回当前边界
    public int pv2(int[] arr, int l, int r) {
        int p = arr[l];
        int left = l + 1;
        int right = r;
        while (left <= right) {
            while (left <= right && arr[left] <= p)
                left++;
            while (left <= right && arr[right] > p)
                right--;
            if (left < right)
                swap(arr, left, right);
        }
        swap(arr, l, right);
        return right;
    }

    // 交换数组中的两个元素
    public void swap(int[] arr, int index1, int index2) {
        int temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是快速排序代码: public class QuickSort { public static void sort(int[] arr, int start, int end){ if (start < end){ int partitionIndex = partition(arr, start, end); sort(arr, start, partitionIndex-1); sort(arr, partitionIndex+1, end); } } private static int partition(int[] arr, int start, int end){ int pivot = arr[end]; int i = start-1; for (int j=start; j<end; j++){ if (arr[j] <= pivot){ i++; int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } int temp = arr[i+1]; arr[i+1] = arr[end]; arr[end] = temp; return i+1; } } ### 回答2: 快速排序(Quick Sort)是一种常用的排序算法,通过将待排序的序列分割成两部分,其中一部分所有元素都小于等于另一部分所有元素,然后对这两部分递归地进行排序,最终得到一个有序序列。 下面是使用Java编写的快速排序代码示例: ```java public class QuickSort { public static void main(String[] args) { int[] array = {5, 2, 9, 4, 7, 1, 6, 8, 3}; quickSort(array, 0, array.length - 1); for (int num : array) { System.out.print(num + " "); } } public static void quickSort(int[] array, int left, int right) { if (left < right) { int pivot = partition(array, left, right); quickSort(array, left, pivot - 1); quickSort(array, pivot + 1, right); } } public static int partition(int[] array, int left, int right) { int pivot = array[right]; int i = left - 1; for (int j = left; j < right; j++) { if (array[j] <= pivot) { i++; swap(array, i, j); } } swap(array, i + 1, right); return i + 1; } public static void swap(int[] array, int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } ``` 以上代码定义了一个`QuickSort`类,其中包含了`main`方法作为程序入口,以及三个静态方法`quickSort`、`partition`和`swap`来实现快速排序算法。 在`main`方法中,首先定义了一个待排序的数组`array`,然后调用`quickSort`方法对该数组进行排序,最后将排序结果输出。 `quickSort`方法用于递归地进行快速排序,它接收一个数组、一个左边界索引`left`和一个右边界索引`right`作为参数。在`quickSort`方法中,首先通过`partition`方法将数组分割为两部分,然后对这两部分分别调用`quickSort`方法进行递归排序。 `partition`方法用于分割数组,它接收一个数组、一个左边界索引`left`和一个右边界索引`right`作为参数。在`partition`方法中,首先选择数组的最后一个元素作为基准值`pivot`,然后通过一个循环将小于等于基准值的元素放置在左侧,大于基准值的元素放置在右侧,最后将基准值放置在中间位置,并返回该位置索引。 `swap`方法用于交换数组中的两个元素,它接收一个数组和两个索引作为参数,然后将对应索引位置的元素进行交换。 以上就是使用Java生成快速排序代码的简单示例。 ### 回答3: 快速排序是一种常用的排序算法,它基于分区的概念,通过找到一个基准元素,将数组分成两个子数组,其中一个子数组的所有元素小于等于基准元素,另一个子数组的所有元素大于等于基准元素,然后递归地对子数组进行排序。 在Java中,可以使用以下代码来实现快速排序: ```java public class QuickSort { public static void quickSort(int[] arr, int low, int high) { if (low < high) { int pivotIndex = partition(arr, low, high); quickSort(arr, low, pivotIndex - 1); quickSort(arr, pivotIndex + 1, high); } } public static int partition(int[] arr, int low, int high) { int pivot = arr[high]; int i = low - 1; for (int j = low; j < high; j++) { if (arr[j] <= pivot) { i++; swap(arr, i, j); } } swap(arr, i + 1, high); return i + 1; } public static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } public static void main(String[] args) { int[] arr = {9, 2, 5, 1, 0, 8, 3}; quickSort(arr, 0, arr.length - 1); for (int num : arr) { System.out.print(num + " "); } } } ``` 运行这段代码会将数组 `{9, 2, 5, 1, 0, 8, 3}` 进行快速排序,并输出排序后的结果:`0 1 2 3 5 8 9`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值