QuickSort 拿下!

article/2025/9/22 6:07:20

剑指 Offer 45. 把数组排成最小的数
  输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

  由于这一题的解题思路是:首先将数组转换为字符数组,然后根据规则对其进行排序;排序的时候可以用到QuickSort(快速排序),又是一个没有系统研究过的tag,因此,特地对其进行一个仔细研究。
在这里插入图片描述

目录

  • 首先是代码
  • 然后是快速排序的思路
  • 最后是实现
  • 边界问题
    • 执行完一次快排后的情况
    • 递归最后满足什么条件退出?
  • c++完整代码
  • 快排的优化

首先是代码

void QuickSort2(vector<int>& arr,int left,int right){//快速排序,每次选取第一个元素作为基准数据,将数组分为两个部分,//左边的元素都小于基准数据,右边的元素都大于基准数据。if(left>=right)return;int low=left;int high=right;while(low<high){while(low<high&&arr[high]>=arr[left])high--;while(low<high&&arr[low]<=arr[left])low++;swap(arr[low],arr[high]);}swap(arr[left],arr[low]);QuickSort2(arr,left,low-1);QuickSort2(arr,low+1,right);
}

然后是快速排序的思路

  例如 [49, 38, 65, 97, 23]
首先选取第一个元素49,将余下的元素按照大小关系分布在49的两边,我们可以规定:比49小,放在左边,比49大,放在右边;
   此时就是:[左边数组,49,右边数组]。这就是一次快速排列后的结果;
   紧接着,我们同样对左边数组、右边数组使用快速排列,直到最后数组里面只有一个元素,此时数组里面的顺序就完成了!
   思路就是这样,先不要想实现,思路你有了吗,是不是很easy!

最后是实现

  我们可以采用递归的思路,例如我们的函数是QuickSort();当我们调用的时候,先执行一次快排,这样我们就将数组按照大小关系分布在了第一个元素的左右两边,然后调用QuickSort(左边数组),QuickSort(右边数组);
我最开始的思路是这样的:

void QuickSort(vector<int>& arr,int left,int right){//快速排序,每次选取第一个元素作为基准数据,将数组分为两个部分,//左边的元素都小于基准数据,右边的元素都大于基准数据。if(left>=right)return;int low=left;int high=right;int tmp=arr[low];while(low<high){while(low<high&&arr[high]>=tmp)high--;arr[low]=arr[high];while(low<high&&arr[low]<=tmp)low++;arr[high]=arr[low];}arr[low]=tmp;QuickSort(arr,left,low-1);QuickSort(arr,low+1,right);
}

而后,才修改成了上述QuickSort2的形式,两种都大同小异;

边界问题

执行完一次快排后的情况

 此时 low=high ;但是,QuickSort2里面 swap(arr[left],arr[low]);,此时如果arr[low]>arr[left]的话,岂不是排了个寂寞?

    swap(arr[left],arr[low]);QuickSort2(arr,left,low-1);QuickSort2(arr,low+1,right);

不存在这种情况: low指向的一定是比arr[left]小的数据,所以,如果在low的后面有比arr[left]大的数据,一定会被high遍历淘汰。

递归最后满足什么条件退出?

 我们每次都是使用一个数据将数组分为两部分,然后对这两部分进行快速排列。

    QuickSort2(arr,left,low-1);QuickSort2(arr,low+1,right);

当由左右边界限定的数组长度小于2的时候,就可以退出了;当只有一个数的时候,显然不用排序,当left>right的时候,显然也不用,因为已经越界了
(越界的情况何时产生:例如[49,38,37,44,23],第一次快排后,low=high=4,此时调用: QuickSort2(arr,low+1,right);就会产生越界的情况)
在这里插入图片描述

c++完整代码

#include<iostream>
#include<vector>
using namespace std;void QuickSort(vector<int>& arr,int left,int right){//快速排序,每次选取第一个元素作为基准数据,将数组分为两个部分,//左边的元素都小于基准数据,右边的元素都大于基准数据。if(left>=right)return;int low=left;int high=right;int tmp=arr[low];while(low<high){while(low<high&&arr[high]>=tmp)high--;arr[low]=arr[high];while(low<high&&arr[low]<=tmp)low++;arr[high]=arr[low];}arr[low]=tmp;QuickSort(arr,left,low-1);QuickSort(arr,low+1,right);
}void QuickSort2(vector<int>& arr,int left,int right){//快速排序,每次选取第一个元素作为基准数据,将数组分为两个部分,//左边的元素都小于基准数据,右边的元素都大于基准数据。if(left>=right)return;int low=left;int high=right;while(low<high){while(low<high&&arr[high]>=arr[left])high--;while(low<high&&arr[low]<=arr[left])low++;swap(arr[low],arr[high]);}swap(arr[left],arr[low]);QuickSort2(arr,left,low-1);QuickSort2(arr,low+1,right);
}
int main(){vector<int> Arr={49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22};QuickSort2(Arr,0,Arr.size()-1);return 0;}

快排的优化

  这几天又刷了LC912. 排序数组,没有想到官方不讲武德,测试集里面新增加了一个很长的有序数组,那么我之前写的快排就会退化为时间复杂度为O(N2) ,这个时候就需要对快排进行一个优化,就是每次不是选取第一个元素作为基准,而是随机选取;
只需要增加一句即可:

void QuickSort3(vector<int>& arr,int left,int right){//快速排序,每次选取第一个元素作为基准数据,将数组分为两个部分,//左边的元素都小于基准数据,右边的元素都大于基准数据。if(left>=right)return;//随机选取一个元素作为本次的基准//(right - left + 1) 总共有几个数 //rand() % (right - left + 1) 随机选取一个数//rand() % (right - left + 1) + left 这个数的实际下标int i = rand() % (right - left + 1) + left;swap(arr[left], arr[i]);int low=left;int high=right;while(low<high){while(low<high&&arr[high]>=arr[left])high--;while(low<high&&arr[low]<=arr[left])low++;swap(arr[low],arr[high]);}swap(arr[left],arr[low]);QuickSort2(arr,left,low-1);QuickSort2(arr,low+1,right);
}

http://chatgpt.dhexx.cn/article/0XECXjYu.shtml

相关文章

经典算法之快速排序(QuickSort)

​ 活动地址&#xff1a;CSDN21天学习挑战赛 目录 快速排序算法原理图解Java代码实现 算法分析 快速排序 通过一趟排序将待排元素分成独立的两部分&#xff0c;其中一部分为比基准数小的元素&#xff0c;另一部分则是比基准数大的元素。然后对这两部分元素再按照前面的算法进行…

QuickSort(快速排序)——C语言实现

前言&#xff1a; 快速排序可真是太经典啦&#xff01;当然&#xff0c;我的复现并没有实现调用一个排序参考函数来实现对不同类型数据进行排序这一功能。 快速排序其中的一大重要思想就是分而治之&#xff0c;采取不断二分的方式进行排序&#xff0c;时间复杂度O&#xff08;n…

快速排序算法Quicksort()

快速排序的思想是用数组的首元素作为标准将A划分成前后两部分&#xff0c;比首元素小的元素构成数组的前部分&#xff0c;比首元素大的元素构成数组的后部分&#xff0c;这两部分构成两个新的子问题&#xff0c;算法接着分别对这两部分递归进行排序 伪代码&#xff1a; 输入&am…

QuickSort c++

QuickSort c 简介 算法导论 原理 from Wiki 执行顺序&#xff1a; 左侧排序完 在执行右侧 实验结果&#xff1a; C code #include"QUICKSORT.h" #pragma once #include<vector>int Partition(std::vector<int>& A, const int& p, const…

java快速排序quicksort

public class QuickSortDemo {public static void main(String[] args) {int[] arr {12,36,56,44,9,44,18};sort(arr , 0 , arr.length-1);System.out.println("排序后&#xff1a;"Arrays.toString(arr));}public static void sort(int[] arr, int left, int right…

QuickSort

一、结果显示 二、QuickSort.h #include<iostream>using namespace std;template<class T> class QuickSort { private:T a[10] {d,a,f,c,v,b,a,g,s,z};int size sizeof(a); public:QuickSort(){cout<<"size "<<size<<endl;}void…

快速排序(QuickSort)算法介绍

算法简介 快速排序&#xff08;Quicksort&#xff09;是对冒泡排序的一种改进算法。由C. A. R. Hoare在1960年提出。该算法使用广泛、效率很高&#xff0c;是最重要的排序算法之一。 该算法的实现基本可分为以下几步&#xff1a; 在数组中选一个基准数&#xff08;通常为数组…

快速排序(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 ■乱码问题解决 ・修改这里…