Java实现快速排序算法

Java实现快速排序算法

算法思路:

快速排序是基于分治法的思想
利用三数中值分割法寻找支点,并将支点左侧的元素全部小于支点元素,支点右侧的元素全部大于支点元素,然后将此数组分为三个部分,支点,支点左边子数组和支点右边子数组。然后不断的对左右两部分进行此方法,一直到子数组的长度小于3,退出递归程序后即为排序好的数组

寻找支点的方法:

将数组的最左边和最右边和中间的元素进行由小到大的排序,并取中间元素的值作为支点,保证a[left]<pivot<a[right],并将此支点移动到最右边元素的左边。

分割的方法:

定义ij,分别指向左右两边,将i从左向右移动,一直移动到大于支点的元素的位置,将j从右向左移动,一直移动到小于支点的元素的位置,如果此时i < j,则将i和j对应位置元素互换,重复此方法,一直到i > j,最后将i对应的元素和支点元素互换,这样就确保了支点元素的左边均小于支点元素,而支点元素的右边均大于支点元素。

Java代码实现:

public class QuickSort {
    public static void main(String[] args) {
        int[] a = {90, 90,67, 3, 8, 43, 89, 90, 90};
        System.out.print("原数组为:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+",");
        }
        System.out.println();
        quickSort(a, 0, a.length - 1);
        System.out.print("快速排序后的数组为:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+",");
        }
    }

    private static void quickSort(int[] a, int left, int right) {
        //递归出口,如果子数组长度小于3,则return
        if (right - left <= 1) return;
        //利用三数中值法找到支点
        int pivot = findPivot(a, left, right);
        int i = left;
        int j = right - 1;
        for (; ; ) {
            //使用a[++i]和a[--j]此方法为了防止当数组中的元素全相同时陷入死循环
            while (a[++i] < pivot) {
            }
            while (a[--j] > pivot) {
            }
            if (i < j) {
                swap(a, i, j);
            } else {
                break;
            }
        }
        //将pivot对应的数组元素与i交换,使得pivot的左边是小元素,右边是大元素
        swap(a, i, right - 1);
        //对支点左边的子数组和支点右边的子数组进行排序
        quickSort(a, left, i - 1);
        quickSort(a, i + 1, right);
    }

    private static void swap(int[] a, int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }

    //  寻找支点的方法,将两个端点和中间位置的三个元素的中间元素值作为支点
    //  顺便让left小于支点元素小于right,可以减少一次比较次数
    private static int findPivot(int[] a, int left, int right) {
        int mid = (left + right) / 2;
        if (a[left] > a[mid]) {
            swap(a, left, mid);
        }
        if (a[right] < a[mid]) {
            swap(a, right, mid);
        }
        if (a[left] > a[right]) {
            swap(a, left, right);
        }
        //将支点元素移动到最右边元素的左边,这样可以减少一次比较次数
        swap(a, mid, right - 1);
        return a[right - 1];
    }
}
代码运行结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值