当前位置: 首页 > news >正文

数据结构-常见的七大排序

上节中我们学习了七大排序中的五种(插入排序、希尔排序、堆排序、选择排序、交换排序)

数据结构-常见的七大排序-CSDN博客

这节我们将要学习快速排序(hoare、指针法、挖洞法(快排的延伸)、快速排序非递归(栈))

 1.快速排序

1.1 hoare法

1.1思路

1.选出一个key,一般是最左边或是最右边的。
2.定义一个begin和一个end,begin从左向右走,end从右向左走。(需要注意的是:若选择最左边的数据作为key,则需要end先走;若选择最右边的数据作为key,则需要bengin先走)。
3.在走的过程中,若end遇到小于key的数,则停下,begin开始走,直到begin遇到一个大于key的数时,将begin和right的内容交换,end再次开始走,如此进行下去,直到begin和end最终相遇,此时将相遇点的内容与key交换即可。(选取最左边的值作为key)
4.此时key的左边都是小于key的数,key的右边都是大于key的数
5.将key的左序列和右序列再次进行这种单趟排序,如此反复操作下去,直到左右序列只有一个数据,或是左右序列不存在时,便停止操作,此时此部分已有序

1.2单趟动图如下:

1.3画图思路如下(单边) 

代码如下:

//快速排序   hoare版本(左右指针法)
void QuickSort(int* arr, int begin, int end)
{//只有一个数或区间不存在if (begin >= end)return;int left = begin;int right = end;//选左边为keyint keyi = begin;while (begin < end){//右边选小   等号防止和key值相等    防止顺序begin和end越界while (arr[end] >= arr[keyi] && begin < end){--end;}//左边选大while (arr[begin] <= arr[keyi] && begin < end){++begin;}//小的换到右边,大的换到左边swap(&arr[begin], &arr[end]);}swap(&arr[keyi], &arr[end]);keyi = end;//[left,keyi-1]keyi[keyi+1,right]//无限向下分,直到一个数或为NULLQuickSort(arr, left, keyi - 1);QuickSort(arr,keyi + 1,right);
}

时间复杂度:
在这里插入图片描述
快速排序的过程类似于二叉树其高度为logN,每层约有N个数,如下图所示:

在这里插入图片描述

2.1前后指针法

2.1思路

1.选出一个key,一般是最左边或是最右边的。
2.起始时,prev指针指向序列开头,cur指针指向prev+1。
3.若cur指向的内容小于key,则prev先向后移动一位,然后交换prev和cur指针指向的内容,然后cur指针++;若cur指向的内容大于key,则cur指针直接++。如此进行下去,直到cur到达end位置,此时将key和++prev指针指向的内容交换即可。

经过一次单趟排序,最终也能使得key左边的数据全部都小于key,key右边的数据全部都大于key。

然后也还是将key的左序列和右序列再次进行这种单趟排序,如此反复操作下去,直到左右序列只有一个数据,或是左右序列不存在时,便停止操作

2.2单趟动图如下: 

代码如下:

//快速排序法  前后指针版本
void QuickSort2(int* arr, int begin, int end)
{if (begin >= end)return;int cur = begin, prev = begin - 1;//前后指针int keyi = end;while (cur != keyi){if (arr[cur] < arr[keyi] && ++prev != cur){swap(&arr[cur], &arr[prev]);}++cur;}swap(&arr[++prev],&arr[keyi]);keyi = prev;//[begin,keyi -1]keyi[keyi+1,end]//与hoare类似,但又有不同QuickSort2(arr, begin, keyi - 1);QuickSort2(arr, keyi + 1, end);}

3.1挖洞法

3.1思路

挖坑法思路与hoare版本(左右指针法)思路类似
1.选出一个数据(一般是最左边或是最右边的)存放在key变量中,在该数据位置形成一个坑
2、还是定义一个L和一个R,L从左向右走,R从右向左走。(若在最左边挖坑,则需要R先走;若在最右边挖坑,则需要L先走)

3.2单趟动图如下:

代码如下: 

//快速排序法  挖坑法
void QuickSort1(int* arr, int begin, int end)
{if (begin >= end)return;int left = begin,right = end;int key = arr[begin];//这里的key就为洞while (begin < end){//找小while (arr[end] >= key && begin < end){--end;}//小的放到左边的坑里arr[begin] = arr[end];//找大while (arr[begin] <= key && begin < end){++begin;}//大的放到右边的坑里arr[end] = arr[begin];}arr[begin] = key;int keyi = begin;//[left,keyi-1]keyi[keyi+1,right]QuickSort1(arr, left, keyi - 1);QuickSort1(arr, keyi + 1, right);
}

4.1快速排序非递归(栈)

与hoare快排类似,这里是利用栈的特点(先进后出,后进先出)

代码如下:

int PartSort2(int* a, int left, int right)
{// 三数取中,为了提高排序效率//这里可以省略int midi = GetMidi(a, left, right);Swap(&a[left], &a[midi]);int keyi = left;int prev = left;int cur = prev + 1;while (cur <= right){if (a[cur] < a[keyi] && ++prev != cur)Swap(&a[prev], &a[cur]);cur++;}Swap(&a[prev], &a[keyi]);return prev;
}
void QuickSortNonHeap(int* a, int left, int right) {Stack st;StackInit(&st);StackPush(&st, right);StackPush(&st, left);while (!StackEmpty(&st) ){int begin = StackTop(&st);STpop(&st);int end = StackTop(&st);STpop(&st);int keyi = PartSort2(a, begin, end);if (keyi + 1 < end){StackPush(&st, end);StackPush(&st, keyi + 1);}if (begin < keyi - 1){StackPush(&st, keyi - 1);StackPush(&st, begin);}}StackDestroy(&st);
}

2.计数排序

2.1思路

计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。 操作步骤:
1. 统计相同元素出现次数
2. 根据统计的结果将序列回收到原来的序列中

代码如下: 

void CountSort(int* a, int n) {int min = a[0], max = a[0];//找最小最大for (int i = 0; i < n; i++) {if (a[i] > max) {max = a[i];}if (a[i] < min) {min = a[i];}}int range = max - min + 1;//calloc开辟空间,存放值为0//malloc开辟空间,存放值为任意值;int* count = (int*)calloc(range, sizeof(int));if (count == NULL){perror("calloc fail");return;}//统计次数for (int i = 0; i < n; i++) {count[a[i] - min]++;}//排序int j = 0;for (int i = 0; i < range; i++) {while (count[i]--) {a[j++] = i + min;}}free(count);
}
计数排序的特性总结:
1. 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限。
2. 时间复杂度:O(MAX(N,范围))
3. 空间复杂度:O(范围)
4. 稳定性:稳定

排序算法复杂度与稳定性

我们学习排序算法的目的是为了更快的效率,如下列举了基本算法的时间复杂度、空间复杂度,及稳定性

对于少量数据,可用冒泡排序、直接插入排序、简单排序排序,相对简单

对于大量数据,可用堆排序、快速排序归并排序,但要注意他们的使用条件

相关文章:

数据结构-常见的七大排序

上节中我们学习了七大排序中的五种(插入排序、希尔排序、堆排序、选择排序、交换排序) 数据结构-常见的七大排序-CSDN博客 这节我们将要学习快速排序(hoare、指针法、挖洞法(快排的延伸)、快速排序非递归(栈)) 1.快速排序 1.1 hoare法 1.1思路 1.选出一个key&#xff0c;一…...

离线安装部署springboot+vue系统到服务器

注意&#xff1a;首先服务器会有多个网卡&#xff0c;这些服务器的网卡连接所需要的文件可能不是我们默认的ifcfg-eth0/ifcfgens33,可以试着切换一下服务器网线插入的接口&#xff0c;要保证服务器网线插入的接口和网卡对应的文件一致 说明&#xff0c;在一些政府&#xff08;保…...

【STM32】ADC模拟数字转换(规则组单通道)

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 ADC简介 ADC时钟配置 引脚模拟输入模式 规则组通道选择 ADC初始化 工作模式 数据对齐 触发转换方式 连续与单次转换模式 扫描模式 组内的通道个数 ADC初始化框架 ADC上电 ADC校…...

WPF 数据模板DataTemplate、控件模板ControlTemplate、Style、ItemsPreseter

一言蔽之&#xff0c;Template就是“外衣”—— ControlTemplate是控件的外衣&#xff0c; DataTemplate是数据的外衣。 DataTemplate 它定义了一个数据对象的可视化结构 DataTemplate常用的地方有3处&#xff0c;分别是&#xff1a; ContentControl的ContentTemplate属性&…...

Windows下搭建Telegraf+Influxdb+Grafana(详解一)

InfluxDB&#xff08;时序数据库&#xff09;&#xff0c;常用使用场景&#xff1a;监控数据统计。 grafana&#xff0c;用作监控页面的前端展示。 telegraf&#xff0c;数据采集器。 所有的安装包都上传到网盘 链接: https://pan.baidu.com/s/1Lv6UnfueK7URx7emAatoYg 提取…...

同城搭子社交系统开发同城搭子群活动APP圈子动态小程序

引言 随着互联网技术的飞速发展&#xff0c;同城搭子社交系统作为一种新兴的社交模式&#xff0c;正逐渐在市场中占据一席之地。该系统通过搭子群活动和圈子动态等功能&#xff0c;为用户提供了一种高效、精准的社交体验。本文将从市场前景、使用人群、盈利模式以及运营推广等…...

大厂最佳实践 | Stripe 如何防止重复付款

为什么扣了我两笔钱&#xff1f; 2010年&#xff0c;美国加利福尼亚州的两兄弟打算创办一家公司&#xff0c;但他们发现建立网上支付十分困难。于是&#xff0c;他们决定开发一款在线支付服务&#xff0c;并将其命名为Stripe。 随着用户数量的不断增长&#xff0c;重复付费问题…...

Raspberry Pi Pico 2 上实现:实时机器学习(ML)音频噪音抑制功能

Arm 公司的首席软件工程师 Sandeep Mistry 为我们展示了一种全新的巧妙方法&#xff1a; 在 Raspberry Pi Pico 2 上如何将音频噪音抑制应用于麦克风输入。 机器学习&#xff08;ML&#xff09;技术彻底改变了许多软件应用程序的开发方式。应用程序开发人员现在可以为所需系统整…...

安全自动化和编排:如何使用自动化工具和编排技术来提高安全操作效率。(第二篇)

深入理解Kubernetes环境中的安全自动化与编排&#xff08;第二篇&#xff09; 1. 引言 Kubernetes作为现代容器编排平台的主流选择&#xff0c;正在被越来越多的企业用于部署和管理其容器化应用。在Kubernetes环境中实施安全自动化与编排&#xff0c;既能够提升系统的安全性&…...

HarmonyOS WebView

HarmonyOS WebView Web组件提供基础的前端页面加载的能力&#xff0c;包括加载网络页面、本地页面、html格式文本数据。Web组件提供丰富的页面交互的方式&#xff0c;包括&#xff1a;设置前端页面深色模式&#xff0c;新窗口中加载页面&#xff0c;位置权限管理&#xff0c;C…...

解决elementUI表格里嵌套输入框,检验时错误信息被遮挡

1.表格 自定义错误信息显示div <el-form-item label"租赁价格" prop"supplierId"><el-table-column prop"salePrice" label"销售价" align"center"><template slot-scope"scope"><el-form-…...

Unity读取Android外部文件

最近近到个小需求,需要读Android件夹中的图片.在这里做一个记录. 首先读写部分,这里以图片为例子: 一读写部分 写入部分: 需要注意的是因为只有这个地址支持外部读写,所以这里用到的地址都以 :Application.persistentDataPath为地址起始. private Texture2D __CaptureCamera…...

【5.3 python中的元组】

5.3 python中的元组 Python中的元组&#xff08;Tuple&#xff09;是一种用于存储多个项目&#xff08;可以是不同类型&#xff09;的序列数据结构&#xff0c;但它与列表&#xff08;List&#xff09;不同&#xff0c;主要区别在于元组是不可变的&#xff08;immutable&#…...

Debezium报错处理系列之第116篇:Caused by: java.lang.NumberFormatException: null

Debezium报错处理系列之第116篇:Caused by: java.lang.NumberFormatException: null 一、完整报错二、错误原因三、解决方法Debezium从入门到精通系列之:研究Debezium技术遇到的各种错误解决方法汇总: Debezium从入门到精通系列之:百篇系列文章汇总之研究Debezium技术遇到的…...

【启明智显技术分享】工业级HMI芯片Model3C/Model3A开发过程中问题记录笔记二

一、Model3C/Model3A芯片介绍 Model3C/Model3A是启明智显针对工业、行业以及车载产品市场推出的一款高性能、低成本的工业级HMI&#xff08;Human-Machine Interface&#xff0c;人机界面&#xff09;芯片。两颗芯片硬件PIN TO PIN&#xff1b;区别在于内置的PSRAM大小不同。该…...

Python 函数返回yield还是return?这是个问题

如果你刚入门 Python&#xff0c;你可能之前没有遇到过yield。虽然它看起来很奇怪&#xff0c;但它是你编码工具库中的一个重要工具。在成为 Python 大师的道路上&#xff0c;你必须掌握它。 返回列表的函数 假设有一个函数&#xff0c;它可以一次性生成一系列值&#xff0c;…...

Linux系统性能调优

Linux系统性能调优是一个复杂而细致的过程&#xff0c;涉及硬件、软件、内核参数、进程管理等多个方面。以下将从多个角度详细介绍Linux系统性能调优的技巧&#xff0c;旨在帮助用户提升系统的运行效率和稳定性。 一、硬件层面的调优 内存升级&#xff1a; 增加物理内存可以减…...

PHPStorm 环境配置与应用详解

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; PHPStorm 是 JetBrains 出品的一款专业 PHP 集成开发环境&#xff08;IDE&#xff09;&#xff0c;凭借其智能的代码补全、调试功能、深度框架支持和前端开发工具&#xff0c;为用户提供了丰富的功能和工具…...

前端各种文本文件预览 文本编辑excel预览编辑 pdf预览word预览 excel下载pdf下载word下载

前端各种文本文件预览 文本编辑excel预览编辑 pdf预览word预览 excel下载pdf下载word下载 各种文本文件预览&#xff08;pdf, xlsx, docx, cpp, java, sql, py, vue, html, js, json, css, xml, rust, md, txt, log, fa, fasta, tsv, csv 等各种文本文件&#xff09; 其中 除p…...

【Qt】QPluginLoader 类学习

文章目录 一、简介二、常用方法2.1 构造函数2.2 动态加载方法——load()2.3 检查是否加载成功——isLoaded()2.4 访问插件中的根组件——instance()2.5 卸载插件——unload() 一、简介 QPluginLoader 类在运行时加载插件。 QPluginLoader 提供对Qt插件的访问。Qt插件存储在共享…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...