快速排序算法

文章目录

  • 一、前言
  • 二、快速排序算法的基本思想
  • 三、快速排序算法流程
  • 四、实现快速排序算法的Java代码
  • 五、分析代码实现过程
    • 1.partition方法
    • 2.quickSort方法
    • 3.swap方法
    • 4.main方法
    • 5.整体串讲
  • 六、对快速排序算法的时间复杂度和稳定性进行讨论
  • 七、对快速排序算法的空间复杂度分析比较
  • 八、总结

一、前言

快速排序(Quicksort),计算机科学词汇,适用领域Pascal,c++等语言,是对冒泡排序算法的一种改进。本次实现使用的Java代码。

二、快速排序算法的基本思想

快速排序算法是一种常用的排序算法,它的基本思想是通过选取一个基准值,将待排序的序列分成两个部分,使得左半部分的所有元素均小于等于基准值,右半部分的所有元素均大于等于基准值,然后对左右两部分递归地进行快速排序,直到整个序列有序为止。

三、快速排序算法流程

快速排序的流程如下:

选取基准值pivot。
将序列中小于等于pivot的元素放在左边,大于pivot的元素放在右边。
对左右两个子序列递归执行步骤1和步骤2,直到子序列长度为1。
快速排序算法的核心在于如何选取基准值,这里我们采用选取序列中间的元素作为基准值的方式。

四、实现快速排序算法的Java代码

下面是用Java实现快速排序算法的代码:

public class QuickSort {
    public static void sort(int[] nums) {
        if (nums == null || nums.length <= 1) {
            return;
        }
        quickSort(nums, 0, nums.length - 1);
    }

    private static void quickSort(int[] nums, int left, int right) {
        if (left >= right) {
            return;
        }
        int pivotIndex = partition(nums, left, right);
        quickSort(nums, left, pivotIndex - 1);
        quickSort(nums, pivotIndex + 1, right);
    }

    private static int partition(int[] nums, int left, int right) {
        int pivot = nums[(left + right) / 2];
        while (left <= right) {
            while (nums[left] < pivot) {
                left++;
            }
            while (nums[right] > pivot) {
                right--;
            }
            if (left <= right) {
                swap(nums, left, right);
                left++;
                right--;
            }
        }
        return left;
    }

    private static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
  public static void main(String[] args) {
        int[] dataArray = new int[]{10, 6, 9, 20, 22, 3, 2, 6, 9};
        sort(dataArray);
        System.out.println(Arrays.toString(dataArray));
    }

在这里插入图片描述

五、分析代码实现过程

1.partition方法

该方法实现了快速排序算法的划分操作,输入参数为待排序数组arr、左边界low和右边界high,返回值为枢轴元素pivot的下标。该方法通过选取arr[low]作为枢轴元素,然后遍历数组,将小于枢轴元素的元素交换到数组的左边,大于枢轴元素的元素交换到数组的右边,最终得到一个划分结果。该方法返回枢轴元素的下标pivot,以便后续递归调用。

2.quickSort方法

该方法是快速排序算法的入口,输入参数为待排序数组arr、左边界low和右边界high,无返回值。该方法首先判断数组的长度是否大于1,如果是,则调用partition方法将数组划分为两部分,然后递归调用quickSort方法分别对划分得到的两部分进行排序。

3.swap方法

该方法用于交换数组中的两个元素,输入参数为数组arr和两个下标i和j,无返回值。该方法通过中间变量temp实现交换。

4.main方法

该方法是程序的入口,用于测试quickSort方法的正确性。在该方法中,定义了一个整型数组arr,初始化后调用quickSort方法对其进行排序,并打印排序结果。

5.整体串讲

首先是quickSort方法。该方法接收一个整数数组nums和两个整数left和right,表示需要对nums中从下标left到下标right的元素进行快速排序。该方法首先判断left是否小于right,如果小于,则调用partition方法,将数组nums中从下标left到下标right的元素划分为两部分,其中左边部分的元素都小于右边部分的元素。然后对左右两部分分别递归调用quickSort方法,直到左右部分均有序。

接下来是partition方法。该方法接收一个整数数组nums和两个整数left和right,表示需要将数组nums中从下标left到下标right的元素划分为两部分,并返回划分后左部分的最后一个元素的下标。该方法首先将left作为枢轴元素的下标pivotIndex,将nums[left]作为枢轴元素pivot。然后从下标left+1开始遍历数组nums,如果遇到一个元素nums[i]小于枢轴元素pivot,则将pivotIndex加1,将元素nums[i]与元素nums[pivotIndex]交换位置,保证左部分的元素均小于枢轴元素。最后将枢轴元素pivot与元素nums[pivotIndex]交换位置,并返回pivotIndex。

最后是swap方法,该方法用于交换数组nums中下标为i和j的两个元素的位置。

六、对快速排序算法的时间复杂度和稳定性进行讨论

快速排序算法的时间复杂度为O(nlogn),其中n为待排序的序列长度。这是因为,在每一次划分时,我们都将序列分成两个长度大致相等的部分,因此每次划分的时间复杂度为O(n),而快速排序算法的递归深度为O(logn),因此总的时间复杂度为O(nlogn)。

快速排序算法不是一种稳定的排序算法,因为在交换元素时,有可能会改变相同元素的相对位置。例如,如果待排序的序列为{3, 1, 3, 2, 4},在第一次划分后得到的序列为{2, 1, 3, 3, 4},其中两个3的相对位置发生了改变。

总之,快速排序算法是一种高效的排序算法,它的时间复杂度为O(nlogn),但不是一种稳定的排序算法。

七、对快速排序算法的空间复杂度分析比较

对于快速排序算法,其空间复杂度为O(logn)。具体而言,快速排序算法在排序过程中需要使用递归调用,每一次递归调用都需要在栈上分配一定的空间,这些空间最终会在递归结束时依次释放,所以在空间复杂度方面表现相对较好。

相对于空间复杂度为O(n)的插入排序和冒泡排序等排序算法,快速排序的空间复杂度确实较低。但需要注意的是,由于快速排序算法是一种递归算法,因此在处理数据规模较大的情况下,可能会导致递归调用过深,占用的栈空间过大,从而导致栈溢出的问题。因此,在实际使用时需要对算法进行优化,避免出现这种问题。

八、总结

快速排序是一种高效的排序算法,其核心思想是分治法。快速排序的基本思路是先选取一个枢轴元素,通过一趟排序将待排序序列分成两部分,其中左边部分的所有元素都小于等于枢轴元素,右边部分的所有元素都大于等于枢轴元素,然后分别递归地对左右两部分进行排序,直到整个序列有序。

具体来说,快速排序算法分为三个步骤:

  • 划分:选取一个枢轴元素,通过一趟排序将待排序序列分成两部分,其中左边部分的所有元素都小于等于枢轴元素,右边部分的所有元素都大于等于枢轴元素。

  • 递归排序:对左右两部分分别递归调用快速排序算法,直到序列有序。

  • 合并:由于每次划分都可以将序列分成两个部分,因此可以将已排序的左右两部分合并成一个有序的序列。

快速排序算法的优点是原址排序,不需要额外的存储空间;并且在大多数情况下具有较好的平均时间复杂度,最坏情况下的时间复杂度也能通过一些优化措施得到改善。缺点是最坏情况下的时间复杂度较差,可能会导致时间复杂度退化为O(n^2)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/17820.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

USB2.0(一):基础

一、总线标准 USB1.1&#xff1a;支持12Mbps全速率&#xff08;FullSpeed&#xff09;和1.5Mbps低速率&#xff08; HalfSpeed&#xff09;USB2.0&#xff1a;支持480Mbps高速率&#xff08;High Speed&#xff09;&#xff0c;兼容1.1USB3.0&#xff1a;支持5Gbps超高速率&am…

asp.net+sqlserver学生学籍管理系统

1.系统登录模块&#xff1a;为了保证系统的安全性和保密性&#xff0c;便于用户的管理&#xff0c;对用户设置权限。 界面上需要输入用户名、密码、验证码以及用户类型。 用户类型&#xff1a;普通用户和管理员用户。 2.用户信息管理模块&…

HarmonyOS版的“抖音”长啥样?有图有真相

“鸿蒙系统实战短视频App 从0到1掌握HarmonyOS”系列课程是面向HarmonyOS实战的视频教程&#xff0c;该课程会通过构建一个真实的短视频App来向读者展示HarmonyOS的全过程。 本节将演示基于HarmonyOS短视频App的核心功能。通过了解该App的功能&#xff0c;也能初步对本课程的内…

Android-实现一个登录页面(kotlin)

准备工作 首先&#xff0c;确保你已经安装了 Android Studio。如果还没有安装&#xff0c;请访问 Android Studio 官网 下载并安装。 前提条件 - 安装并配置好 Android Studio Android Studio Electric Eel | 2022.1.1 Patch 2 Build #AI-221.6008.13.2211.9619390, built …

5---最长回文字串

给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s “babad” 输出&#xff1a;“bab” 解释&#xff1a;“aba” 同样是符合题意的答案。 示例 2&…

自行车和电动自行车上亚马逊标准有什么区别?UL2849,16CFR1512

自行车 自行车是一种两轮的或三轮的交通工具&#xff0c;完全靠人力驱动后轮前进。本政策所涵盖的自行车包括当座位调整到最高位置时&#xff0c;座位离地面超过 25 英寸的自行车&#xff0c;以及座位高度为 25 英寸或以下的人行道自行车。本政策也适用于公路使用的卧式自行车…

2023-05-04:用go语言重写ffmpeg的scaling_video.c示例,用于实现视频缩放(Scaling)功能。

2023-05-04&#xff1a;用go语言重写ffmpeg的scaling_video.c示例&#xff0c;用于实现视频缩放&#xff08;Scaling&#xff09;功能。 答案2023-05-04&#xff1a; 这段代码实现了使用 libswscale 库进行视频缩放的功能。下面是程序的主要流程&#xff1a; 1.获取命令行参…

MySQL事务

1、事务的概念 事务是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这一组数据库命令要么都执行&#xff0c;要么都不执行。 事务是一个不可分割的工作逻辑单元&#xff…

推荐一些非常好用的DNS服务器

推荐一些非常好用的DNS服务器 1、114公共DNS服务器 1&#xff09; 老牌的114DNS&#xff0c;全国三网通用高速&#xff0c;纯净无劫持无需再忍受被强扭去看广告或粗俗网站之痛苦 DNS地址为&#xff1a;114.114.114.114 和 114.114.115.115 2&#xff09;拦截 钓鱼病毒木马网…

【目标检测论文阅读笔记】Dynamic Head: Unifying Object Detection Heads with Attentions

Abstract 在目标检测中结合定位和分类的复杂性导致了方法的蓬勃发展。以前的工作试图提高各种目标检测头的性能&#xff0c;但未能提出统一的观点。在本文中&#xff0c;我们提出了一种新颖的动态头部框架 来统一目标检测头部和注意力。通过在用于尺度感知的特征级别之间、用于…

SpringCloud学习笔记06

九十五、Cloud Alibaba简介 0、why会出现SpringCloud alibaba Spring Cloud Netflix项目进入维护模式 1、是什么 官网&#xff1a;spring-cloud-alibaba/README-zh.md at 2.2.x alibaba/spring-cloud-alibaba GitHub 2、能干嘛 3、去哪下 spring-cloud-alibaba/README-…

【软考高项笔记】第3章 信息系统治理(针对甲方)3.1 IT治理

第3章 信息系统治理&#xff08;针对甲方&#xff09; 3.1 IT治理 不同于管理&#xff0c;角度更高3.1.1 IT治理基础 目标价值 与业务目标一致 有效利用信息与数据资源 风险管理 管理层次 最高管理层 &#xff08;定目标&#xff0c;战略&#xff09; 执行管理层 &#xff08…

【BingChat】Microsoft Edge/Bing Chat 注册使用完全指南

欢迎关注【youcans的学习笔记】原创作品&#xff0c;火热更新中 【BingChat】Microsoft Edge/Bing Chat 注册使用完全指南 1. BingChat 简介2. BingChat 用户注册2.1 下载微软浏览器 Edge 预览版2.2 申请微软账户2.3 登录 Bing.com2.4 手机/平板使用 BingChat 3. BingChat 的聊…

4.shell函数

文章目录 shell函数shell函数的作用函数返回值函数传参函数变量作用范围递归阶乘使用函数递归目录/var/log&#xff0c;如果是文件直接输出文件名&#xff0c;如果是目录则输出目录名且输出此目录下的所有目录和文件名通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录…

【Jmeter快速入门】

Jmeter快速入门 Jmeter快速入门1.安装Jmeter1.1.下载1.2.解压1.3.运行 2.快速入门2.1.设置中文语言2.2.基本用法 Jmeter快速入门 1.安装Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量。 1.1.下载 可以Apache Jm…

SSM整合详细教学(上)

SSM整合详细教学&#xff08;上&#xff09; 一、SSM整合1. SSM整合配置1.1 SSM整合流程1.2 SSM整合配置1.2.1 创建工程&#xff0c;添加依赖和插件1.2.2 Spring整合Mybatis1.2.3 Spring整合SpringMVC 2. 功能模块开发2.1 数据层开发(BookDao)2.2 业务层开发(BookService/BookS…

TIM编码器接口

一、知识点 1、Encoder Interface 编码器接口的工作流程 编码器接口可接收增量&#xff08;正交&#xff09;编码器的信号&#xff0c;根据编码器旋转产生的正交信号脉冲&#xff0c;自动控制CNT自增或自减&#xff0c;从而指示编码器的位置、旋转方向和旋转速度 2、编码器接口…

「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构和CQRS的整合

这篇文章是软件架构编年史的一部分&#xff0c;一系列关于软件架构的文章。在这些文章中&#xff0c;我写了我对软件架构的了解&#xff0c;我如何看待它&#xff0c;以及我如何使用这些知识。如果您阅读了本系列以前的文章&#xff0c;那么本文的内容可能更有意义。 今天的帖子…

【多任务学习】Multi-task Learning 手把手编码带数据集, 一文吃透多任务学习

文章目录 前言1.多任务学习1.1 定义1.2 原理 2. 多任务学习code2.1 数据集初探2.2 预处理2.3 网络结构2.4 训练 3. 总结 前言 我们之前讲过的模型通常聚焦单个任务,比如预测图片的类别等,在训练的时候,我们会关注某一个特定指标的优化. 但是有时候,我们需要知道一个图片,从它身…

PostgreSQL 基础知识:psql 提示和技巧

对于积极使用和连接到 PostgreSQL 数据库的任何开发人员或 DBA 来说&#xff0c;能够访问psql命令行工具是必不可少的。在我们的第一篇文章中&#xff0c;我们讨论了 psql的简要历史&#xff0c;并演示了如何在您选择的平台上安装它并连接到 PostgreSQL 数据库。 在本文中&…