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

article/2025/9/22 6:47:13

前言:

        快速排序可真是太经典啦!当然,我的复现并没有实现调用一个排序参考函数来实现对不同类型数据进行排序这一功能。

        快速排序其中的一大重要思想就是分而治之,采取不断二分的方式进行排序,时间复杂度O(nlog(n)),当然最坏的情况是每次都得二分,复杂度会到O(n^2)

空间复杂度由于涉及到递归的复杂度,我本身理解的也不是很深刻,就不误人子弟了,推荐这篇文章,关于复杂度的部分写的很好!链接放下头了:

———————————————————————————————————————————

2022.11.27,链接失效了= =,不知道为啥

http://t.csdn.cn/lJDzg

———————————————————————————————————————————

思路:

        快速排序的基本思路就是不断对数组进行二分,分而治之进行排序的,需要用到递归的知识。我们举个栗子:

574692

        1.那么,如何进行二分?如其名,二分,我们首先需要准备两个指针 left 和 right,正如其名,一个最初指向需要排序的最左边的下标,一个指向需要排序的最右边的下标。但是,具体写代码过程中我们函数需要的形参我使用了left 和 right 来传递需要进行排序的区间,所以在函数内部,我们使用 i 来代表left,j 来代表right。

574692
ij

        2.然后,我们需要制定一个进行排序的标准大小,通常使用需要排序的数组中的第一个元素,比较方便使用。我们最终需要的状态是这个元素的左边都是比他小的数(不必在乎顺序)右边都是比他大的数字。(显然,这个元素不在最初的位置,当然我们也可以开辟一个辅助数组来进行存储,不过没有这个必要),最终需要得到下列这个形式,那么思考我们如何可以得到这样一个数组

(其实得到这样一个数组,基本就理解这个算法了,剩下的就是进行递归,简简单单两行,所以精髓就是理解如何得到如下的数组。)

425697
i,j

首先,我们定义一个flag,用来标记最初的排序基准数(为了方便我们选择数组的第一个数)。因为不能同时从两边移动 i 和 j 因此我们需要确定一下先动谁,这个地方的不一样会导致整体代码有微小的差异,这里我选择的是先动左边的 j 。

然后我们回顾一下整体的思路,需要把比基准数大的移到右边,比基准数小的移到左边。

因此,我们的 j 的移动标准就是比基准数大的数我们不管他(因为J是从最右边开始移动的,而右边的都得是比基准数大的数),如果遇到比基准数小的数,我们停下。

然后移动 i ,i 的移动标准就是比基准数小的数我们不管他,遇到比基准数大的数我们停下。然后交换 i, j 下标对应的数,一次交换完成。

因为要不停的交换,所以我们外层套的判断条件应该是while,条件呢?当 i 和 j 相遇了,我们就不用继续往下交换数字了,所以我们可以写 i != j 作为判断条件,当然放宽一些,最好写 i < j 作为判断条件。同时,这里我们需要注意内层移动 i 和 j 的时候,会出现 j 移动到 i 左边(因为这是内层的循环,外层控制不到)所以,内层的几个while 和 if 我们都需要套上判断条件 i < j 。

while (i < j){while (arr[j] >= flag && i < j)j--;while (arr[i] <= flag && i < j)i++;if (i < j)swap(&arr[i], &arr[j]);}

用我们举得列子来说我们就变成了这样:

524697
ji

这样就很好理解了,我们还需要把 j 对应下标的数字 同一开始的基准数进行一次交换。得到第一次排序的最终样式:

425697
ji

        3.第一次排序我们完成了,接下来我们只需要用递归的思路,对标记左边的,右边的两端分别递归调用函数就可以了。其中左右差不多,说一下左边的范围 [left, j-1] 因为基准的位置是 j ,同时基准数的位置是合理的。所以,我们接下来需要排序的就是不包含基准数的右边半区的数组,最左边界自然是我们传入的排序左边界left,因此范围是[left, j-1]。

//这边为什么用j呢?因为
QuickSort(arr,left,j - 1);
QuickSort(arr,j + 1,right);

写到这,我们可以在函数最前头上加上一个简单出口,加快函数的执行效率:

if (left >= right)return;

 因为当我们进行递归调用的时候,必然会把长度区间缩小,缩小到1的时候就没必要进行排序了,这也是这个函数的出口之一。

 完整排序代码如下:

void QuickSort(int *arr,int left,int right)
{if (left >= right)return;int i, j;int flag = arr[left];i = left, j = right;while (i < j){while (arr[j] >= flag && i < j)j--;while (arr[i] <= flag && i < j)i++;if (i < j)swap(&arr[i], &arr[j]);}swap(&arr[left],&arr[j]);QuickSort(arr,left,j - 1);QuickSort(arr,j + 1,right);
}

测试代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 30//之前写过了,就不再全写一遍了
void generate_random_number(int*, int, int);
void swap(int*, int*);void QuickSort(int *arr,int left,int right)
{if (left >= right)return;int i, j;int flag = arr[left];i = left, j = right;while (i < j){while (arr[j] >= flag && i < j)j--;while (arr[i] <= flag && i < j)i++;if (i < j)swap(&arr[i], &arr[j]);}swap(&arr[left],&arr[j]);QuickSort(arr,left,j - 1);QuickSort(arr,j + 1,right);
}int main()
{int arr[N + 10] = { 0 };generate_random_number(arr, 0, 1024);QuickSort(arr,0,N-1);printf("排序后数列:\n");for (int i = 0; i < N; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

 测试结果如下:

至此,QuickSort(快速排序)完成


http://chatgpt.dhexx.cn/article/YmTk7T8g.shtml

相关文章

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

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…