【算法】快速排序的原理与Java实现

简介: 快速排序(Quick Sort)是一种常用且高效的排序算法,基于分治(Divide and Conquer)策略。它的基本思想是选择一个基准元素,通过将待排序的数组划分为两个子数组,使得左边的子数组中的元素都小于等于基准元素,右边的子数组中的元素都大于等于基准元素。然后对左右子数组分别进行快速排序,最终将排序好的子数组合并起来,得到完整的有序数组。

一.快速排序原理


快速排序(Quick Sort)是一种常用且高效的排序算法,基于分治(Divide and Conquer)策略。它的基本思想是选择一个基准元素,通过将待排序的数组划分为两个子数组,使得左边的子数组中的元素都小于等于基准元素,右边的子数组中的元素都大于等于基准元素。然后对左右子数组分别进行快速排序,最终将排序好的子数组合并起来,得到完整的有序数组。


快速排序的具体步骤如下:

1.选择基准元素:从待排序的数组中选择一个元素作为基准(通常选择第一个元素或最后一个元素)。

2.划分操作:将数组中小于等于基准元素的元素放在基准元素的左边,将大于等于基准元素的元素放在基准元素的右边,使得基准元素的位置确定。

3.递归排序:对基准元素左边的子数组和右边的子数组分别进行快速排序,重复步骤2。

4.合并结果:将左边子数组、基准元素、右边子数组合并起来,得到最终的有序数组。


二.使用Java实现快速排序


public class QuickSort {
    public static void main(String[] args) {
        int[] arr = {5, 2, 8, 3, 1};
        System.out.println("Before sorting:");
        printArray(arr);
        quickSort(arr, 0, arr.length - 1);
        System.out.println("After sorting:");
        printArray(arr);
    }
    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++;
                // 将小于等于基准元素的元素交换到左边
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        // 将基准元素放到正确的位置上
        int temp = arr[i + 1];
        arr[i + 1] = arr[high];
        arr[high] = temp;
        return i + 1; // 返回基准元素的位置
    }
    public static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

以上代码使用快速排序算法对一个整数数组进行排序。quickSort方法实现了快速排序的逻辑,首先选择一个基准元素,并通过划分操作将数组中小于等于基准元素的元素放在基准元素的左边,大于等于基准元素的元素放在基准元素的右边。然后对左右子数组分别进行快速排序,最终合并结果。partition方法用于执行划分操作,确定基准元素的位置。


运行以上代码,将输出如下结果:

Before sorting:
5 2 8 3 1 
After sorting:
1 2 3 5 8

快速排序算法的时间复杂度为O(nlogn),其中n是数组的长度。它是一种不稳定的排序算法,适用于任何规模的数组。由于其平均时间复杂度较低且具有原地排序的特性,快速排序是一种常用的排序算法。

相关文章
|
1天前
|
存储 Java
JAVA并发编程AQS原理剖析
很多小朋友面试时候,面试官考察并发编程部分,都会被问:说一下AQS原理。面对并发编程基础和面试经验,专栏采用通俗简洁无废话无八股文方式,已陆续梳理分享了《一文看懂全部锁机制》、《JUC包之CAS原理》、《volatile核心原理》、《synchronized全能王的原理》,希望可以帮到大家巩固相关核心技术原理。今天我们聊聊AQS....
|
8天前
|
缓存 Java 编译器
JAVA并发编程volatile核心原理
volatile是轻量级的并发解决方案,volatile修饰的变量,在多线程并发读写场景下,可以保证变量的可见性和有序性,具体是如何实现可见性和有序性。以及volatile缺点是什么?
|
2天前
|
安全 Java API
JAVA并发编程JUC包之CAS原理
在JDK 1.5之后,Java API引入了`java.util.concurrent`包(简称JUC包),提供了多种并发工具类,如原子类`AtomicXX`、线程池`Executors`、信号量`Semaphore`、阻塞队列等。这些工具类简化了并发编程的复杂度。原子类`Atomic`尤其重要,它提供了线程安全的变量更新方法,支持整型、长整型、布尔型、数组及对象属性的原子修改。结合`volatile`关键字,可以实现多线程环境下共享变量的安全修改。
|
9天前
|
监控 算法 Java
掌握Java的垃圾回收机制:从原理到实践
在Java的世界中,垃圾回收(Garbage Collection,简称GC)是一块神秘的领域,它如同一位默默无闻的清洁工,确保内存中不再使用的对象得到妥善处理。本文将带你走进垃圾回收的大门,探索它的工作原理、常见算法及其在实际应用中的调优策略。无论你是初学者还是有一定经验的开发者,这篇文章都将为你揭开垃圾回收的神秘面纱,让你的Java程序运行得更加高效和稳定。
24 5
|
11天前
|
缓存 Java 编译器
JAVA并发编程synchronized全能王的原理
本文详细介绍了Java并发编程中的三大特性:原子性、可见性和有序性,并探讨了多线程环境下可能出现的安全问题。文章通过示例解释了指令重排、可见性及原子性问题,并介绍了`synchronized`如何全面解决这些问题。最后,通过一个多窗口售票示例展示了`synchronized`的具体应用。
|
7天前
|
Java 开发者 数据格式
【Java笔记+踩坑】SpringBoot基础4——原理篇
bean的8种加载方式,自动配置原理、自定义starter开发、SpringBoot程序启动流程解析
【Java笔记+踩坑】SpringBoot基础4——原理篇
|
1天前
|
Java
JAVA并发编程ReentrantLock核心原理剖析
本文介绍了Java并发编程中ReentrantLock的重要性和优势,详细解析了其原理及源码实现。ReentrantLock作为一种可重入锁,弥补了synchronized的不足,如支持公平锁与非公平锁、响应中断等。文章通过源码分析,展示了ReentrantLock如何基于AQS实现公平锁和非公平锁,并解释了两者的具体实现过程。
|
Java Android开发
【Java 虚拟机原理】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 | 静态变量 )
【Java 虚拟机原理】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 | 静态变量 )
148 0
|
6天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)
|
17天前
|
监控 Java 调度
【Java学习】多线程&JUC万字超详解
本文详细介绍了多线程的概念和三种实现方式,还有一些常见的成员方法,CPU的调动方式,多线程的生命周期,还有线程安全问题,锁和死锁的概念,以及等待唤醒机制,阻塞队列,多线程的六种状态,线程池等
79 6
【Java学习】多线程&JUC万字超详解