快速排序(QuickSort)算法介绍

article/2025/9/22 7:10:52

算法简介

快速排序(Quicksort)是对冒泡排序的一种改进算法。由C. A. R. Hoare在1960年提出。该算法使用广泛、效率很高,是最重要的排序算法之一。

该算法的实现基本可分为以下几步:

  1. 在数组中选一个基准数(通常为数组第一个)。
  2. 将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边
  3. 对于基准数左、右两边的数组,不断重复以上两个过程,直到每个子集只有一个元素,即为全部有序。

示例有一数组为4 1 8 3 7 5,依上面的思路排序过程为

  1. 选第一个基准元素

4 1 3 6 7 5

  1. 以基准元素为中心将数组分成两个子集

3 1 4 6 7 5

  1. 将两个子集重复以上操作,直到全部有序

1 3

5 6 7

  1. 得到有序的集合

1 3 4 5 6 7

以上是快速排序的基本思路,这里比较重要的是第2点,如何将一个数组以基准数为中心分为两部分呢?

快排是这样解决的,假设做正序排序:

在数组的头部和尾部分别设置一个哨兵,同时向对方走去。尾部的哨兵如发现有比基准数小的数,停下。头部的哨兵如发现有比基准数大的数,停下。交换两个数。再重新走重复前面的交换过程。直到两个哨兵相遇,交换基准数和尾哨兵。

有一数组为6 1 2 7 9 3 4 5 10 8,带着这样做为什么可以的态度来看一下演示。

  1. 6为基准数,设i,j为两哨兵,目前指向首尾两个数(加粗部分)。

    6 1 2 7 9 3 4 5 10 8

  2. 两哨兵分别走向对方,直到遇到交换条件,并做交换。

6 1 2 7 9 3 4 5 10 8
6 1 2 5 9 3 4 7 10 8

  1. 此时来观察交换后的队列,除去基准数,是不是哨兵走过的位置都已部分有序了呢? 左边1 2 5都比基准数小,右边7 10 8都比基准数大。

1 2 5 9 3 4 7 10 8

  1. 继续走直到相遇,基准数复位。

6 1 2 5 9 3 4 7 10 8
6 1 2 5 4 3 9 7 10 8
6 1 2 5 4 3 9 7 10 8
3 1 2 5 4 6 9 7 10 8

这样就完美地将一个数组以一个基准数为中心分为两个子集。然后重复这个过程即可实现快速排序。

有一点需特别注意:若以第一个元素为基准数(就如上面的示例),在哨兵互走过程需右边的哨兵先走。 原因很好理解,看上面过程解析就会明白:哨兵互走交换的过程就是不断排序的过程。若右边的哨兵先走,不管走多少次,最后相遇时的那个数是小于基准数的。这时与基准数交换,正好分为两个序列。可若是左边的先走,相遇在大于基准数上就不好办了。

算法实践

以java演示一遍

   public void quickSort(int[] arr, int low, int high) {// low,high 为每次处理数组时的首、尾元素索引//当low==high是表示该序列只有一个元素,不必排序了if (low >= high) {return;}// 选出哨兵元素和基准元素。这里左边的哨兵元素也是基准元素int i = low, j = high, base = arr[low];while (i < j) {//右边哨兵从后向前找while (arr[j] >= base && i < j) {j--;}//左边哨兵从前向后找while (arr[i] <= base && i < j) {i++;}swap(arr,i,j);  //交换元素}swap(arr,low,j);  //基准元素与右哨兵交换//递归调用,排序左子集合和右子集合quickSort(arr,low,j-1);  quickSort(arr,j+1,high);}private void swap(int[] arr, int i, int j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}

ForkJoinTask与快速排序

Fork/Join框架是Java7提供了的一个用于并行执行任务的框架。它可以充分利用多核CPU的优势,将一个大任务切割成多个足够小的任务并行执行(fork),等所有子任务执行完毕后合并结果(join),流程图类似下面:

这里写图片描述

图片来自文章聊聊并发(八)——Fork/Join框架介绍。

这样来看,fork/join的处理模式与quickSort算法
倒很相似,都是不断分割任务以进行处理。而事实上,两者都是分治算法的实践者。我们可以将上述排序改成并发版的快速排序。

class SortTask extends RecursiveAction{private int[] arr;private int low;private int high;public SortTask(int[] arr,int low,int high) {this.arr = arr;this.high = high;this.low = low;}@Overrideprotected void compute() {if(low<high){int i=low,j=high,base = arr[low];while (i<j){while (arr[j]>=base&& i<j){j--;}while (arr[i] <= base && i < j) {i++;}swap(arr,i,j);}swap(arr,low,j);SortTask leftTask =new SortTask(arr,low,j-1);SortTask rightTask =new SortTask(arr,j+1,high);//分割成子任务并执行,join()方法会再次调用compute()方法。leftTask.fork();rightTask.fork();leftTask.join();leftTask.join();}}private void swap(int[] arr, int i, int j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}
}

测试结果

    @Testpublic  void test()throws Exception {ForkJoinPool forkJoinPool = new ForkJoinPool();int[] arr = {4, 1, 8, 6, 7, 9, 3, 2};SortTask sortTask = new SortTask(arr,0,arr.length-1);ForkJoinTask<Void> task =  forkJoinPool.submit(sortTask);task.get();Arrays.stream(arr).forEach(e->System.out.print(e+" "));// 1 2 3 4 6 7 8 9}

http://chatgpt.dhexx.cn/article/4V27amYD.shtml

相关文章

快速排序(Quicksort)详解

引言 这篇文章是我在2015年写的&#xff0c;当时正在看算法导论中关于快排的部分&#xff0c;因此写下文章总结一下当时对快排的理解。这几天我一直在review一下我先前写的blog&#xff0c;发现有些地方写的不算太好&#xff0c;还有一些错误的地方。今天我重新修改一下这篇文…

排序——快速排序(Quick sort)

概况 快速排序&#xff08;Quick sort&#xff09;是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1960年提出。 算法思路 通过一趟排序将要排序的数据分割成独立的两部分&#xff0c;其中一部分的所有数据都比另外一部分的所有数据都要小&#xff0c;然后再按此方法对…

Visual Studio 2013 + Intel(R) Visual Fortran 安装教程

安装了好几遍&#xff0c;ivf都不能加载到vs中&#xff0c;中途放弃了vs&#xff0c;又改用codeblocks编译器&#xff0c;依然在写fortran的时候出现了各种问题&#xff0c;于是又放弃了codeblocks改回vs&#xff0c;总之是折腾了好久&#xff0c;终于装明白了ivf并且将fortran…

fortan dll在本地可以运行成功,移植到其他电脑上报错Exception in thread main java.lang.UnsatisfiedLinkError: 找不到指定的模块。

坑&#xff01;&#xff01;&#xff01;大大的坑&#xff01;&#xff01;&#xff01; 本项目需要实现java调用fortran的dll&#xff0c;我在本地编译好apae.dll&#xff0c;然后java调用dll成功&#xff01; 将apae.dll发送给对方&#xff0c;同样的java代码和fortran的dl…

Matlab2017b配置C++/C/Fortan编译器的问题(已解决)

今天在配置Matlab2017编译C代码的时候&#xff0c;一贯的调用mex -setup命令&#xff0c;结果显示没有找到任何支持的编译器或SDK。您可以安装免费的mingw-w64 c/c编译器; 崩溃&#xff01;&#xff01; 最后根据错误所给的链接在matlab2017的获取附加功能安装mingw-w64 、结…

Fortan写出数据到CSV文件中

1.输入代码 program HelloWorldopen(unit60, fileF:\Lambda3.csv)write(60,*) 4.2,5.2/sqrt(2*12550/4.1595e-11)end program HelloWorld 2.结果如下

ABAQUS6.10 VS2008 Intel fortan11.1

1.先参考微博 http://blog.sina.com.cn/s/blog_56d5b3b00100wg2y.html 2. 其它一些资料以及注意事项 IVF 11.1 可用 http://pan.baidu.com/s/1pKWPCq3 用DAEMON tools 安装IVF11.1 DAEMON是个虚拟光驱 VS2008 用英文版 ABAQUS用6.10 6.11 6.12 都安装完之后 找到Commands文件夹…

fluent加载第三方(C++,Fortan等)动态链接库

这里我介绍一种比较简单的方法&#xff0c;首先我们从ANSYS Fluent UDF Manual上随便找一段正确的UDF&#xff0c;下面这段UDF取自ANSYS 18的ANSYS Fluent UDF Manual&#xff0c;位于2.3.23.3. Example 1 - Pressure Profile / *********************************************…

Abaqus运行fortan报错:“Error in job Job-1: Problem during compilation - D:\test.for”

一、简介 最近在学习abaqus的子程序&#xff1b;学习视频为简单实例_哔哩哔哩_bilibili 模型建立后&#xff0c;所写的子程序代码如下&#xff1a; SUBROUTINE DLOAD(F,KSTEP,KINC,TIME,NOEL,NPT,LAYER,KSPT,1 COORDS,JLTYP,SNAME) CINCLUDE ABA_PARAM.INC CDIMENSION TIME(2),…

linux安装go语言环境

linux安装go语言环境 前言环境版本前期知识准备部署步骤安装wget下载压缩包&#xff0c;解压到指定路径/usr/local配置环境变量创建GOPATH文件夹添加PATH环境变量and设置GOPATH环境变量1.打开配置文件2.更改配置信息3.然后执行下面命令使上述环境变量的设置立即生效&#xff1a…

如何修改linux的 系统语言

首先查看当前系统的语言 1、echo $LANG 查看当前操作系统的语言 中文&#xff1a;zh_CN.UTF-8 英文:&#xff1a;en_US.UTF-8 2、临时更改默认语言&#xff0c;当前立即生效 重启失效 export LANGen_US.UTF-8 3、永久生效,修改配置文件 centos7/rhel7之前版本&#x…

如何查看、修改linux系统语言

如何查看、修改linux系统语言 本机环境&#xff1a;CentOS 7.6本文方法适用于&#xff1a;centos7/rhel7之前版本和centos7/rhel7版本 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) 1、查看当前操作系统的语言 echo $LANG 中文&#…

Linux安装日文语言包,以及,TeraTerm显示乱码问题 的 解决

■效果 ■语言包安装 rootsxzap01:~# apt -y install language-pack-ja ■修改配置文件&#xff08;修改之后&#xff0c;需要重新连接&#xff09; 改前&#xff1a;LANGen_US.UTF-8 vi /etc/default/locale 改后&#xff1a;LANGja_JP.UTF-8 ■乱码问题解决 ・修改这里…

Go语言 linux安装

​​​​​1、下载go安装包 载go的linux安装包&#xff0c;比如&#xff1a;go1.15.6.linux-amd64.tar.gz 2、解压 解压至/usr/local下&#xff0c;命令&#xff1a;tar -zxvf go1.15.6.linux-amd64.tar.gz 解压之后&#xff0c;查看版本&#xff1a;/usr/local/go/bin/go …

linux系统设置中文

怎么设置Linux系统中文语言&#xff0c;这是很多小伙伴在开始使用Linux的时候&#xff0c;都会遇到一个问题&#xff0c;就是终端输入命令回显的时候中文显示乱码。出现这个情况一般是由于没有安装中文语言包&#xff0c;或者设置的默认语言有问题导致的。以centos为例&#xf…

Linux 系统语言切换 ---- Linux Ubuntu 系统语言切换为英文

系统&#xff1a;Linux Ubuntu 18.04 中文版 目录 1. 在桌面右键打开命令框&#xff08;Open Terminal&#xff09;&#xff1a; 2. 进入系统默认语言设置文件目录&#xff1a; 3. 打开系统语言配置文件&#xff1a; 4. 打开的系统文件如下&#xff1a; 5. 修改系统文件内容…

设置linux-kali 2022语言为中文(保姆级图文)

目录 友情提示1. 打开终端2. 打开设置3. 修改设置4. 重启生效设置总结 欢迎关注 『网络工程专业』 系列&#xff0c;持续更新中 欢迎关注 『网络工程专业』 系列&#xff0c;持续更新中 在安装完 kali linux2022 时&#xff0c;操作系统默认语言为英文&#xff0c;初学者可以把…

Linux中如何切换中文英文

查看当前使用的是中文(zh_CN.UTF-8)还是英文(LANG"en_US.UTF-8): echo $LANG 进入etc文件&#xff1a; cd /etc 使用vim编辑器进入初始配置的locale.conf文件&#xff1a; vim locale.conf 可以看到我目前的locale.conf文件中只有中文&#xff0c;如图&#xff1a; 目…

嵌入式Linux开发的编程语言选择

欢迎大家关注我的公*号&#xff1a;embedded_bug 这里的嵌入式Linux环境是指非标准Linux发行版环境&#xff0c;比如通过buildroot创建的&#xff0c;相比于标准的Linux发行版比如ubuntu&#xff0c;debian&#xff0c;fedora&#xff0c;系统比较简陋&#xff0c;提供的库很有…

Linux如何修改系统语言

Linux如何修改系统语言 一、Linux如何修改系统语言 对于刚学Linux 的小伙伴&#xff0c;或者英语水平相对低一些的小伙伴&#xff0c;在自己的Linux系统里面如果能直接显示中文&#xff0c;中文提示就是比较爽的一件事了&#xff0c;接触起来也不会觉得头大&#xff0c;不过说…