排序算法:详解快速排序算法及其java实现

1,614 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

作者平台:

| CSDN:blog.csdn.net/qq_4115394…

| 掘金:juejin.cn/user/651387…

| 知乎:www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

| 微信公众号:1024笔记

本文一共1677字,预计阅读7分钟

前言

前面几篇文章介绍了一些比较经典的排序算法,比如冒泡排序插入排序选择排序希尔排序,今天继续学习另一个比较常见的排序算法:快速排序算法。

什么是快速排序

快速排序是一种高效率排序算法,它是对冒泡排序的一种改进,它也是一种不稳定排序。

快速排序算法的核心是比较、交换和递归。它是基于冒泡排序的移动换位思想通过多次的比较和交换从而实现排序,在每一次的排序过程中需要把待排序的序列分为两个独立的部分, 对这两部分的数据进行排序使得其中某一部分的所有数据都比另一部分的数据都要小,然后继续递归重复这两部分,从而实现对所有数据的排序。

快排核心思想如下:

1.首先需要选定一个基准位pivot(可以选定数组的第一个值),比如以左边的低位为基准位:array[low],比基准位的值大的放在右边,基准位值小的放在左边(根据具体的排序需求来)

2、指定两个指针:左边为left、右边为right,并且left<right,如果left>right则退出排序逻辑

3、右边高位指针从右向左遍历并且high--,查找比基准位小的数据,左指针从左向右low++,查找比基准值大的数据

3.如果指针未相遇,交换左右两值位置,如果指针相遇,则替换基准值的位置

4.左递归,右递归

快速排序的java实现

通过上述的逻辑对其进行java实现,代码如下:

public class QuickSort {
    public static void main(String[] args) {
        int[] arr = {4,3,2,1,7,5,0,9,8,6};
        System.out.println("快排之前:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        quickSort(arr,0,arr.length-1);
        System.out.println("\n快排之后:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }

    /**
     *
     * @param arr:待排序的数组
     * @param low:左边低位指针
     * @param high:右边高位指针
     */
    public static void quickSort(int[] arr,int low,int high){
        // 方法退出条件,指针相遇或低位大于高位指针
        if (low >= high) {
            return;
        }
        // 首先指定基准位和左右指针记录位置
        int pivot = arr[low];
        int l = low;
        int r = high;
        int temp = 0;
        // 左指针小于右指针则进行遍历
        while (l < r) {
            // 先进行右边遍历
            while (l < r && arr[r] >= pivot) {
                r--;
            }
            // 左边遍历
            while (l < r && arr[l] <= pivot) {
                l++;
            }
            // 当l指针还在r指针右侧(l<r),表示两指针还未相遇
            if (l < r) {
                temp = arr[l];
                arr[l] = arr[r];
                arr[r] = temp;
            }
        }
        // 当左右指针相遇,则交换基准位的位置
        arr[low] = arr[l];
        arr[l] = pivot;
        // 再根据条件进行左边递归遍历
        if (low < l) {
            quickSort(arr, low, l - 1);
        }
        // 根据条件右边进行递归遍历
        if (r < high) {
            quickSort(arr, r + 1, high);
        }
    }
}

image.png

总结

快速排序是在冒泡排序的基础之上采用了二分的思想对其进行改进,每次的排序过程都需要定一个基准值,小于基准的放在基准的左边,大于基准的放在基准的右边。从而导致每次的交换过程中不会像冒泡排序一样在相邻的元素之间交换,和冒泡排序相比其每次的交换是跳跃的,所以交换的距离更大,所以使得比较和交换的次数也更少了,排序的速度也更快了。所以其平均时间复杂度是O(NlogN),但是仍然会存在和冒泡排序一样的情况,那么这时候的最差时间复杂度也和冒泡排序一样是O(N2),并且因为在排序的过程中相等元素的相对位置会发生变化,所以它仍然是非稳定排序。

其他推荐