排序算法:快速排序

1,快速排序介绍

  • 快速排序是对冒泡排序的一种改进,通过一趟排序将要排序的数据分为独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小;然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,通过多次递归,达到整个数组为有序数组。
  • 基本思想:
    • 先从数组中随机取一个参考值
    • 分别从数组两边(left, right)开始取数据进行比较
    • 如果left取到的数据大于基准数据, right取到的数据小于基准数据, 则进行交换
    • 交换完成后, 对两侧数据分别与参考值比较, 如果与参考值相等, 则对侧进1
    • 一次遍历完成后, 以参考值为中点, 左侧数据小于该值, 右侧数据大于该值
    • 继续递归左右两边进行同样处理, 直到左右两侧数据数量足够小, 则数组有序

2,快速排序示例

在这里插入图片描述

3,快速排序代码实现

package com.self.datastructure.sort;

/**
 * 快速排序
 *
 * @author PJ_ZHANG
 * @create 2020-03-06 15:00
 **/
public class QuickSort {

    private static int count = 0;

    public static void main(String[] args) {
//        int[] array = {6, 8, 9, 1, 4, 3, 5, 6, 8};
        // 10万个数测试, 44ms
        // 100万测试, 193ms
        // 1000万测试, 2224ms
        int[] array = new int[10000000];
        for (int i = 0; i < 10000000; i++) {
            array[i] = (int) (Math.random() * 8000000);
        }
        long startTime = System.currentTimeMillis();
        quickSort(array, 0, array.length - 1);
//        System.out.println(Arrays.toString(array));
        System.out.println("cast time : " + (System.currentTimeMillis() - startTime));
        System.out.println("调用次数: " + count);
    }

    // 快速排序
    // 先从数组中随机取一个参考值,
    // 分别从数组两边(left, right)开始取数据进行比较
    // 如果left取到的数据大于基准数据, right取到的数据小于基准数据, 则进行交换
    // 交换完成后, 对两侧数据分别与参考值比较, 如果与参考值相等, 则对侧进1
    // 一次遍历完成后, 以参考值为中点, 左侧数据小于该值, 右侧数据大于该值
    // 继续递归左右两边进行同样处理, 知道左右两侧数据数量足够下, 则数组有序
    private static void quickSort(int[] array, int left, int right) {
        count++;
        int l = left;
        int r = right;
        // 取一个基本值
        int baseData = array[l];
        // 从两边开始进行判断
        while (l < r) {
            // 取左侧大于等于基本值的数据
            while (array[l] < baseData) {
                l++;
            }
            // 取右侧小于等于基本值的数据
            while (array[r] > baseData) {
                r--;
            }
            // 如果此时l大于等于r, 说明一趟已经比较完成, 直接退出
            if (l >= r) {
                break;
            }
            // 进行数据交换
            int temp = array[l];
            array[l] = array[r];
            array[r] = temp;
            // 因为上面已经进行过交换
            // 如果l侧数据与基础数据相等,则r测数据一定大于基础数据, r--
            if (array[l] == baseData) {
                r--;
            }
            // 如果r侧数据与基础数据相等,则l测数据一定小于基础数据, l++
            if (array[r] == baseData) {
                l++;
            }
        }
        // 出循环后, 说明一组基于基础值的数据已经比较完毕, 此时如果l = r, 则错开数据
        // 两侧分别进1
        // 如果不添加该部分, 可能会栈溢出
        if (l == r) {
            l++;
            r--;
        }
        // 以当前基准值为中点, 左侧为小于该值的数据, 右侧为大于该值的数据, 递归进行两侧处理, 直到数据有序
        if (left < r) {
            quickSort(array, left, r);
        }
        if (l < right) {
            quickSort(array, l, right);
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值