Java快排算法

快排算法

快排就是快速排序,是通过不断比较和移动交换来进行排序,相当于冒泡排序的一种升级。

其基本思想是:

分而治之,也就是把一组数组分成两个独立数组,再对两个独立的数组再次进行排序。

其步骤为:

第一步确定分界点,一般分界点可取左边界、中间值、右边界或者随机值。
第二步调整区间,使得所以小于分界点的值放在左边,所以大于分界点的值放在右边。
第三步进行递归处理,先把左边进行排序,再把右边排序。

package com.jinyu.day01;

import java.util.Arrays;

public class Code04_QuickSort {


    public static void quickSort(int[] arr, int left, int right) {
        if (left < right) {
            //随机下标的元素跟最后元素互换
            swap(arr, left + (int) (Math.random() * (right - left + 1)), right);
            int[] p = partition(arr, left, right);
            quickSort(arr, left, p[0] - 1);
            quickSort(arr, p[1] + 1, right);
        }
    }

    //这是一个处理arr[l...r]的函数
    //默认以arr[r]这个数进行划分,arr==p[r]  <p ==p >p
    //返回的是等于区域的左右边界
    public static int[] partition(int[] arr, int left, int right) {
        int less = left - 1; //<区右边界
        int more = right;// >区左边界
        while (left < more) {  //l表示当前数的位置  arr[r]表示的是划分值
            //当前数小于划分数 则当前数与 <区 的右边界的第一个数交换然后 <区 的右边界右移一位 left也要加1
            if (arr[left] < arr[right]) {
                swap(arr, left++, ++less);//理解left++, ++less的含义
            } else if (arr[left] > arr[right]) {//当前数大于划分数时 当前数与 >区 前一个数交换, >区 左边界左移一位
                swap(arr, --more, left);
            } else { //如果当前数与划分数相等,则只需要当前数往前走一位就行
                left++;
            }
        }
        swap(arr, more, right);//处理划分数
        return new int[]{less + 1, more};
    }

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

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

快排最需要注意的就是partition(int[] arr, int left, int right),他是快排算法的核心,它的作用就是将数组按照分界点划分成左右两个子序列,左序列所有数据都小于分节点,右序列所有序列都大于分界点,这里还需要注意,需要排序的数组里面存在可能存在着重复元素,因此partition的返回值是一个数组,其含义是左序列的右边界和右序列的左边界。

partition这个思想还会在topK问题中运用到。

性能分析

稳定性

由于在快速排序中,元素的比较和交换是跳跃进行的,所以快速排序是一种不稳定的排序算法。

复杂度分析

快速排序的平均时间复杂度是O(nlogn),但是在实际排序中,时间复杂度和基准元素(枢轴)的选择有关。如果枢轴选取不好,那么快速排序有可能就会退化为冒泡排序,时间复杂度为O(n*n)。
由于快速排序是通过递归实现的,而递归又要依靠栈空间来实现,所以快速排序相对于其它排序更耗费空间资源。
通常来说,为了避免快速排序退化为冒泡排序,以及递归栈过深的问题,我们一般依据“三者取中”的法则来选取基准元素,“三者”即序列首元素、序列尾元素、序列中间元素,在三者中取中值作为本趟快速排序的基准元素

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值