快速排序(qsort)

2023-11-15

快速排序

排序方法有很多种:选择排序,冒泡排序,归并排序,快速排序等。 看名字都知道快速排序是目前公认的一种比较好的排序算法。

快速排序的核心思想是二分法。
在此,我以升序为例。

首先,我们需要选取一个基准数temp,再通过循环比较,将比基准数小的放在左边,大的放右边,然后把基准数归位。之后,用递归,将每一段二分,直到所有数都归位,此时每段左边都比右边小,完成排序。
在这里插入图片描述

代码如下:

#include <stdio.h>
int a[101],n;//定义全局变量,这两个变量需要在子函数中使用
void quicksort(int left, int right) {	
	int i, j, t, temp;
		
	if(left > right) //终止条件		
		return;
		    
	temp = a[left]; //temp中存的就是基准数    
	i = left;    
	j = right;    
	
	while(i != j) { //顺序很重要,要先从右边开始找  
	  	
		while(a[j] >= temp && i < j)    		
			j--;    	
			
		while(a[i] <= temp && i < j)//再找右边的    		
			i++;           	
			
		if(i < j)//交换两个数在数组中的位置   
		{    		
			t = a[i];    		
			a[i] = a[j];    		
			a[j] = t;    	
		}    
	}    
	
	//最终将基准数归位    
	a[left] = a[i];    
	a[i] = temp;    
	
	quicksort(left, i-1);//继续处理左边的,这里是一个递归的过程    
	quicksort(i+1, right);//继续处理右边的 ,这里是一个递归的过程
}
int main() {	
	int i;    //读入数据	
	scanf("%d", &n);	
	
	for(i = 1; i <= n; i++)		
		scanf("%d", &a[i]);    
		
	quicksort(1, n); //快速排序调用    
	
	//输出排序后的结果    
	for(i = 1; i < n; i++)    	
		printf("%d ", a[i]);    
	printf("%d\n", a[n]);    
	
	return 0;
}

因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用。 这就是qsort函数(全称quicksort)。它是ANSI C标准中提供的,其声明在stdlib.h文件中,其时间复杂度为n*log(n)。

接下来,我将介绍怎么直接调用c语言stdlib.h库中 qsort 函数。

首先,函数原型为
void qsort(void *base, size_t nitems, size_t size, int (*compare)(const void , const void))

其中
base– 指向要排序的数组的第一个元素的指针。
nitems– 由 base 指向的数组中元素的个数。
size– 数组中每个元素的大小,以字节为单位。
compare– 用来比较两个元素的函数,即函数指针(回调函数)

compare函数写法为:

int comp(const void*a,const void*b)
{
	return *(int *)a - *(int *)b;//由小到大(升序)
	return *(int *)b - *(int *)a;//由大到小(降序)
}
Compare 函数的返回值 描述
< 0 a将被排在b前面
0 a 等于 b
> 0 a 将被排在b后面

以下是不同类型下,使用qsort的模板样例:
1)对一维数组的排序实例:

#include<stdio.h>
#include<stdlib.h>
int comp(const void*a,const void*b)
{
	return *(int*)a-*(int*)b;
}
int main()
{
	int i=0;
	int *array;
	int n;
	scanf("%d",&n);
	array=(int*)malloc(n*sizeof(int)); 
	for(;i<n;i++)
	{
		scanf("%d",(array+i));
	}
	
	qsort(array,n,sizeof(int),comp);
	
	for(i=0;i<n;i++)
	{
		printf("%d\t",array[i]);
	}
	return 0;
}

对一个二维数组进行排序:

int a[1000][2]; 

int comp(const void*a,const void*b) 
{
	return((int*)a)[0]-((int*)b)[0];
}

qsort(a,1000,sizeof(int)*2,comp); 

其中按照a[0]的大小进行一个整体的排序,其中a[1]必须和a[0]一起移动交换。//即第一行和第二行(a[0]和a[1]分别代表第一行和第二行的首地址)。使用库函数排序的代码量并不比用冒泡排序法小,但速度却快很多。

(2)对字符串进行排序

int Comp(const void*p1,const void*p2)
{
	return strcmp((char*)p2,(char*)p1);
}
int main()
{
	char a[MAX1][MAX2];
	initial(a);//初始化a
	qsort(a,lenth,sizeof(a[0]),Comp);//lenth为数组a的长度
}

(3)按结构体中某个关键字排序(对结构体一级排序):

structNode
{
	double data;
	int other;
}s[100];

int Comp(const void*p1,const void*p2)
{
	return(*(Node*)p2).data>(*(Node*)p1).data?1:-1;
}

qsort(s,100,sizeof(s[0]),Comp);

按结构体中多个关键字排序(对结构体多级排序)[以二级为例]:

struct Node
{
int x;
int y;
}s[100];//按照x从小到大排序,当x相等时按y从大到小排序

int Comp(const void*p1,const void*p2)
{
	struct Node*c=(Node*)p1;
	struct Node*d=(Node*)p2;
	if(c->x!=d->x)
		return c->x-d->x;
	else 
		return d->y-c->y;
}

对结构体中字符串进行排序:

struct Node
{
	int data;
	char str[100];
}s[100];//按照结构体中字符串str的字典序排序

int Comp(const void*p1,const void*p2)
{
	return strcmp((*(Node*)p1).str,(*(Node*)p2).str);
}

qsort(s,100,sizeof(s[0]),Comp);

此次对快速排序的讲解及应用就这些了,卑微的菜菜czp在这里感谢读者们的支持。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

快速排序(qsort) 的相关文章

  • 归并排序(递归,非递归)

    目录 写在前面的话 一 归并思想 二 归并排序递归实现 2 1思想实现 2 2排序实现 2 3代码实现 三 归并排序非递归实现 3 1思路实现 小区间优化 3 2边界值处理 3 2代码实现 写在前面的话 小伙伴们大家好啊 今天依旧小菜鸡库森
  • C/C++排序

    目录 C排序 头文件 使用 C 排序 头文件 使用 1 自定义类型 2 自定义类型 C排序 C语言中排序函数为qsort 原理为快速排序 头文件 在使用前 要添加头文件如下 include
  • 堆排序(Heapsort)-- 高级排序算法

    1 堆排序 Heapsort 堆排序 Heapsort 是指利用堆这种数据结构所设计的一种排序算法 二叉堆本质上是一种完全二叉树 它分为两个类型 最大堆和最小堆 最大堆任何一个父节点的值 都大于等于它左右孩子节点的值 最小堆任何一个父节点的
  • 快速排序————非递归实现

    二 递归实现快速排序 2 1 为什么我们要去通过递归实现我们的快速排序呢 大家有可能会想是不是因为递归非常的占用空间 我们都知道我们的局部变量是保存在栈上的我们的函数参数也是在栈上开辟的 所以说递归是不是会占用我们非常多的栈空间 同时呢我们
  • 数据结构-将升序数组转化为平衡二叉搜索树-java

    1 题目 给定一个升序排序的数组 将其转化为平衡二叉搜索树 BST 平衡二叉搜索树指树上每个节点 node 都满足左子树中所有节点的的值都小于 node 的值 右子树中所有节点的值都大于 node 的值 并且左右子树的节点数量之差不大于1
  • CH1-绪论

    文章目录 算法时间复杂度的计算 一 冒泡排序简介 从小到大排序 算法时间复杂度的计算 我们一般只关心随着问题规模n趋于无穷时 函数中对函数结果影响最大的项 比如说 T n 3n 3 当n非常大的时候 常数3和n的系数3对函数结果的影响就很小
  • 计数排序基础思路

    所谓计数排序 也可以称为散列表 也是一种简单的哈希桶 今天 小编带大家来了解计数排序的基本思路 一 基本思路 以升序为例 计数排序通俗来讲 分为三个步骤 首先制作包含所有要排序的数的桶 相同的数制作一个桶即可 以2 3 6 1 4 1 2
  • 用C语言编写一段堆排序算法

    include
  • R语言基本函数的学习(持续更新)

    目录 前言 Tidyverse包 arrange 函数 head 函数 filter 函数 select 函数
  • c++用vector先按学生的年级排序,再按学生的分数排序算法

    VectorSort cpp 定义控制台应用程序的入口点 include stdafx h include stdio h include string h include
  • 【数据结构】排序(直接插入、折半插入、希尔、冒泡、快速、直接选择、堆、归并、基数排序)

    一 什么是排序 排序 将一组杂乱无章的数据按一定规律顺次排列起来 即 将无序序列的数据节点包含多个数据域 那么排序往往是针对其中某个域而言 二 排序方法的分类 1 按数据存储介质可分为 内部排序 数据量不大 数据在内存 无需内外存交换数据
  • 九种常见排序的比较和实现

    首先排序算法大的可以分为 关键字比较 非关键字比较 关键字比较 关键字比较就是通过关键字之间的比较和移动 从而使整个序列有序 而关键字比较的算法 又可以像下面这样划分 对于排序算法之间的比较 无异于时间复杂度和空间复杂度 看下面这张表格 由
  • 算法相关-经典排序算法(goland实现)

    概述 插入排序 将未排序的元素同已排序的元素从后往前比较 带排序元素 a 被比较元素 b 如果a
  • Insertion插入排序

    原谅我接着偷懒 是真的没有什么写的内容了啊 好怀疑他们那些大佬是怎么那么多的文章和技术分享的 自闭中ing 最好情况的时间复杂度是 O n 最坏情况的时间复杂度是 O n2 然而时间复杂度这个指标看的是最坏的情况 而不是最好的情况 所以插入
  • C语言排序算法实现

    C语言实现各种排序算法 冒泡排序 选择排序 插入排序 希尔排序 插入方式 非交换方式 快速排序 归并排序 分治思想 基数排序 桶排序 基数排序的基本思想 典型的空间换时间方式 冒泡排序 include
  • 【数据结构】带你手撕八大排序

    目录 一 排序的基础知识 1 排序的概念 2 排序的应用 3 常见的排序算法 二 八大排序的实现 1 插入排序 直接插入排序 直接插入排序的特性总结 2 插入排序 希尔排序 希尔排序的特性总结 3 选择排序 直接选择排序 直接插入排序特性总
  • 【模板】快速排序

    题目链接 洛谷 P1177 模板 快速排序 1960年由查尔斯 安东尼 理查德 霍尔 Charles Antony Richard Hoare 缩写为C A R Hoare 提出 如下图所示 快速排序的执行流程为 从序列中选择一个轴点元素
  • 【快速选择算法】O(n)时间复杂度

    快速选择的期望时间复杂度为O n 最坏时间复杂度为O n 2 当每次划分只划分为n 1个和1个时 由于划分时间复杂度为O n 最坏时间复杂度为O n 2 void quickselect vector
  • 八大排序(插入排序 | 选择排序 | 冒泡排序)

    在我们内存中我们一般会有一些没有顺序的数据 我们成为内排序 而今天分享八大排序的是时间复杂度为O N 2 的插入排序 选择排序和教学意义比较强的冒泡排序 插入排序 这是插入排序的动图 通过动图我们也是可以看到我们的插入排序的思想 从当前的位
  • 冒泡排序/选择排序/插入排序/快速排序/归并排序/桶排序/堆排序/希尔排序/计数排序/基数排序/二分查找/广度优先搜索/深度优先搜索

    排序算法 冒泡排序 Bubble Sort 通过重复地比较相邻的元素并交换它们 使得最大 或最小 的元素逐渐移动到列表的一端 从而实现排序 选择排序 Selection Sort 在未排序的部分中 选择最小 或最大 的元素 并将其放置在已排

随机推荐

  • 二十三种设计模式第二十一篇--解释器模式

    解释器模式 Interpreter Pattern 是一种行为设计模式 它用于定义一种语言的语法结构和解释器 使得可以解释并执行特定的语法规则 该模式可以将复杂的语言表达式分解为更小的语法单元 并定义其解释过程 解释器模式的核心组成部分包括
  • NameError: global name ‘***‘ is not defined

    错误示范 class Solution object def fib self n type n int rtype int while n gt 0 if n 1 or n 2 return 1 else return fib n 1 f
  • 手把手带你实现Linux内核编译步骤及配置

    linux 系统体系结构 linux kernel体系结构 arm有7种工作模式 x86也实现了4个不同级别RING0 RING3 RING0级别最高 这样linux用户代码运行在RING3下 内核运行在RING0 这样系统本身就得到了 充
  • linux中把一个文件的内容复制到(或覆盖)另一个文件的末尾

    转载自 https blog csdn net u013991521 article details 80528647 问题描述 比如11的文件内容是 hello 22的文件内容是 world 将22的文件内容复制到11文件的末尾 11文件
  • python类的属性和实例的属性有什么区别

    在 Python 中 类属性和实例属性是两种不同类型的属性 它们在用途和作用域上有所不同 下面是关于它们的区别的详细解释 定义位置 类属性 定义在类的主体中 但在任何类方法之外 实例属性 通常在 init 方法或其他类方法中使用 self
  • 自动化测试工具软测界的不二之选,还不快速来了解

    目录 引言 前言 一 龙测AI TestOps云平台使用教程 1 如何登录龙测AI TestOps云平台 登录方法 登录方法 2 龙测AI TestOps云平台界面布局 3 龙测AI TestOps云平台菜单功能 创建项目 应用管理 设备管
  • 若依框架针对不同用户使用不同样式判断

    在开发中 有时候会针对不同用户使用不同样式 如果使用权限判断符的话会出现 请设置权限的问题 这样我们可以导入若依框架原本的权限判断函数 import checkPermi checkRole from utils permission 权限
  • Hibernate4与hibernate3主要区别与版本不一致导致的错误

    Hibernate版本改动 Hibernate4的改动较大只有spring3 1以上版本能够支持 Spring3 1取消了HibernateTemplate 因为Hibernate4的事务管理已经很好了 不用Spring再扩展了 这里简单介
  • 为何大量网站不能抓取?爬虫突破封禁的6种常见方法

    转载自 https www cnblogs com junrong624 p 5533655 html 在互联网上进行自动数据采集 抓取 这件事和互联网存在的时间差不多一样长 今天大众好像更倾向于用 网络数据采集 有时会把网络数据采集程序称
  • FileZilla - The free FTP solution

    FileZilla The free FTP solution https filezilla project org index php https www filezilla cn 1 Overview The FileZilla Cl
  • JavaScript重写Symbol(Symbol.iterator)实现迭代器(2)

    重写数组for of底层用的迭代器 for of 底层用Symbol Symbol iterator 迭代器 arr 底层用Symbol Symbol iterator 迭代器 示例图 代码 h1 对象遍历重写iterator接口2 h1
  • python中class用法实例

    python中class用法实例 https blog csdn net u010551600 article details 79126911 该程序的作用是找到studet txt文件中 GPA最高的那名同学 并打印出他的信息 程序运行
  • 【机器学习】神经网络介绍【转】

    深度学习 神经网络介绍 1 神经元 2 激活函数 3 感知机与多层网络 4 误差反向传播 参考 周志华 机器学习 神经网络是由具有适应性的简单单元组成的广泛并行互连的网络 它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应 Koho
  • micropython驱动ST7789v 2.4寸液晶显示中文

    一 ST7789v介绍 ST7789v是小尺寸液晶中常用的驱动芯片 作者手里的是网上买的一块2 4寸液晶模组 接口 为SPI接口 网上能找到这个芯片的micropython驱动 这不是本文的重点 本文的重点是如何利用这个驱动 并使用字库的方
  • 记录禁用联想笔记本电脑的触摸板

    触摸板在笔记本打字的时候很容易误操作 于是要关闭 我的这台Lenovo 关闭触摸板方法很直观很简单 键盘最上面一排Fxx的按钮中 F6键上就画着触摸板的小图标 按下F6 就关闭 再按一次 就开启 可能有些电脑不是 只是记录我使用的这台的情况
  • 快速理解事件委托?

    捕获和冒泡允许我们实现一种被称为 事件委托 的强大的事件处理模式 如果我们有许多以类似方式处理的元素 那么就不必为每个元素分配一个处理程序 而是将单个处理程序放在它们的共同祖先上 示例代码
  • 图像&视频编辑工具箱MMEditing使用示例:图像抠图(matting)

    MMEditing的介绍及安装参考 https blog csdn net fengbingchun article details 126331541 这里给出图像抠图的测试代码 论文 Indices Matter Learning to
  • Android Layout设计

    public View onCreateView LayoutInflater inflater ViewGroup container Bundle savedInstanceState Now that CrimeListFragmen
  • 浅谈 one-stage 与 two-stage 目标检测方法

    由于目前实习及找工作的原因 博客更新的频率下降 而在面试过程中也发现 虽然论文是看过了 包括也有输出一些论文笔记 但是很多时候无法形成自己对该领域的一个概括性的认知 无法粗中有细 细中有粗 主要还是基本功不扎实 反应了自己在日常学习中的学习
  • 快速排序(qsort)

    快速排序 排序方法有很多种 选择排序 冒泡排序 归并排序 快速排序等 看名字都知道快速排序是目前公认的一种比较好的排序算法 快速排序的核心思想是二分法 在此 我以升序为例 首先 我们需要选取一个基准数temp 再通过循环比较 将比基准数小的