快速排序与归并排序(非递归)

目录

快速排序(双指针法)

原理

代码

快速排序(非递归)

原理

代码

归并排序

介绍

优点

缺点

图片

原理

代码

归并排序(非递归)

代码


快速排序(双指针法)

快速排序的精髓在于将数组根据关键值分成左右两块,由此衍生出霍尔快排,挖坑法等一系列方法,在这里我们要介绍一下双指针法

原理

第一个指针pre指向开头,第二个指针cur指向第二个元素

cur持续向前查找,找到某个位置小于关键值时,将cur指向的值与pre的下一个值进行交换(没错,是下一个,这样就可以将第一个位置的关键值保存下来)

交换还有个限制条件就是pre的下一个位置不能是cur

交换完成后cur与pre指向下一个位置

循环退出条件为cur超出数组范围

退出循环后,将pre位置的值与关键值进行交换(因为pre位置始终小于关键值)

最后和普通的递归一样递归执行左右两侧即可

代码

void quicksort(int* arr, int left, int right) {//双指针if (left >= right)return;int cur = left + 1, pre = left;while (cur <= right) {if (arr[cur] < arr[left] && ++pre < cur)swap(&arr[cur], &arr[pre]);cur++;}swap(&arr[left], &arr[pre]);quicksort(arr, left, pre - 1);quicksort(arr, pre + 1, right);
}

快速排序(非递归)

原理

我们可以使用栈进行模拟递归,首先创建一个栈,将数组的左右边界打入栈中,进入循环

当栈不为空时持续执行循环

根据自己的实际情况判断左右边界,如果先打入的是右边界,那么栈顶元素就是左边界

取出左右边界后,执行一次快排并返回关键值所在位置

如果关键值左侧不止一个元素,那么就打入左侧的左右边界

右侧同理

这样,我们就实现了非递归的快速排序

代码

int part(int* arr, int left, int right) {if (left >= right)return 0;int cur = left + 1, pre = left;while (cur <= right) {if (arr[cur] < arr[left] && ++pre < cur)swap(&arr[cur], &arr[pre]);cur++;}swap(&arr[left], &arr[pre]);return arr[pre];
}
void quicksort1(int* arr, int left, int right) {//非递归Stack stack;StackInit(&stack);StackPush(&stack, right);StackPush(&stack, left);while (!StackEmpty(&stack)) {int begin = StackTop(&stack);StackPop(&stack);int end = StackTop(&stack);StackPop(&stack);int key = part(arr, begin, end);if (key - 1 > begin) {StackPush(&stack, key-1);StackPush(&stack, begin);}if (key + 1 < end) {StackPush(&stack, end);StackPush(&stack, key + 1);}}
}

归并排序

介绍

归并排序是通过不断细分左右边界,使局部有序后扩大范围使整体有序的排序

优点

效率较高,且不会受原数组排列顺序影响

缺点

需要额外开辟一块等大的数组

图片

原理

创建等大的辅助数组

拆分为两块数组

先递归自身使左右两边有序

与链表类似

比较分成的两块有序数组的元素大小并排列在辅助数组中

整体有序后拷贝到原数组中

代码

void _Mergesort(int* arr, int*tmp,int left,int right) {if (left >= right)return;int mid = (left + right) / 2;int begin1 = left, end1 = mid, begin2 = mid + 1, end2 = right,i=left;_Mergesort(arr, tmp, begin1, end1);_Mergesort(arr, tmp, begin2, end2);while (begin1 <= end1 && begin2 <= end2) {if (arr[begin1] < arr[begin2]) {tmp[i++] = arr[begin1];begin1++;}else {tmp[i++] = arr[begin2];begin2++;}}while (begin1 <= end1) {tmp[i++] = arr[begin1];begin1++;}while (begin2 <= end2) {tmp[i++] = arr[begin2];begin2++;}memcpy(arr + left, tmp + left, sizeof(int) * (right - left + 1));
}

归并排序(非递归)

我们要用到希尔排序时创建的一个变量:gap

gap为一个数组拆分后单个小数组的元素个数

最小为一

当gap小于总数时

按照gap为一组,两组为一大组的顺序从左到右进行排序

当右侧起始位置超出时,直接退出,因为左侧小数组本身就是有序的

右侧终止位置超出时修正即可

单次遍历结束后将辅助数组元素拷贝回原数组即可

代码

void MergesortNonR(int* arr, int n) {int gap = 1;//gap为每小组元素个数,两个小组为一大组进行比较int* tmp = (int*)malloc(sizeof(int) * n),i;while (gap < n) {for (i = 0; i < n; i+=2*gap) {int begin1 = i, end1 = begin1 + gap - 1;int begin2 = end1 + 1, end2 = begin2 + gap - 1, j = i;if (begin2 >= n)break;if (end2 >= n)end2 = n - 1;while (begin1 <= end1 && begin2 <= end2) {if (arr[begin1] > arr[begin2])tmp[j++] = arr[begin2++];elsetmp[j++] = arr[begin1++];}while (begin1 <= end1)tmp[j++] = arr[begin1++];while (begin2 <= end2)tmp[j++] = arr[begin2++];memcpy(arr + i, tmp + i, sizeof(int) * gap * 2);}gap *= 2;}free(tmp);tmp = NULL;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/21223.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年06月编程语言流行度排名

点击查看最新编程语言流行度排名&#xff08;每月更新&#xff09; 2024年06月编程语言流行度排名 编程语言流行度排名是通过分析在谷歌上搜索语言教程的频率而创建的 一门语言教程被搜索的次数越多&#xff0c;大家就会认为该语言越受欢迎。这是一个领先指标。原始数据来自…

【30天精通Prometheus:一站式监控实战指南】第15天:ipmi_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们&#x1f44b;   欢迎加入【30天精通Prometheus】专栏&#xff01;&#x1f4da; 在这里&#xff0c;我们将探索Prometheus的强大功能&#xff0c;并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。&#x1f680;   Prometheus是云原生和DevOps的…

(奇幻森林)POLYGON - Enchanted Forest - Nature Biomes - 3D Environment Art by Synty

各种雄伟的树木,装饰着优雅简化的树叶,在头顶形成了一个天堂般的树冠,在苔藓覆盖的森林地面上投下了宁静的咒语。 每一项资产,从引人入胜的环境材料到平缓的波浪状山丘,都经过精心制作,将您带到魔法和自然融合的地方。POLYGON-魔法森林-自然生物技术为数字领域注入真正魔…

60 关于 SegmentFault 的一些场景 (2)

前言 呵呵 此问题主要是来自于 帖子 月经结贴 -- 《Segmentation Fault in Linux》 这里主要也是 结合了作者的相关 case, 来做的一些 调试分享 当然 很多的情况还是 蛮有意思 本文主要问题如下 1. 访问异常堆栈地址1 2. 访问异常堆栈地址2 3. 访问异常堆栈地址3 4. sta…

第三届大湾区算力大会丨暴雨开启数字未来新篇

5月30-31日&#xff0c;韶关市迎来主题为“算启新篇智创未来”的第三届粤港澳大湾区(广东)算力产业大会暨第二届中国算力网大会&#xff0c;活动由广东省人民政府主办&#xff0c;广东省政数局、韶关市人民政府共同承办。暴雨信息作为算力产业发展的重要构建者受邀赴会&#xf…

Java的数据库编程-----JDBC

目录 一.JDBC概念&使用条件&#xff1a; 二.mysql-connector驱动包的下载与导入&#xff1a; 三.JDBC编程&#xff1a; 使用JDBC编程的主要五个步骤&#xff1a; 完整流程1&#xff08;更新update&#xff09;&#xff1a; 完整流程2(查询query)&#xff1a; 一.JDB…

汪小菲直播翻车亲儿子直言麻六记有异味网友热议引爆话题

汪小菲直播翻车&#xff01;亲儿子直言“麻六记”有“异味”&#xff0c;网友热议引爆话题在星光璀璨的娱乐圈&#xff0c;汪小菲一直以家庭幸福、事业有成的形象示人。然而&#xff0c;近日的一场直播让他遭遇了前所未有的尴尬。在直播中&#xff0c;汪小菲兴致勃勃地向观众跨…

视频搬运的素材网站有哪些?打包好的视频素材在哪找?

短视频创作的朋友们&#xff0c;欢迎进入这个充满创意的世界&#xff01;如果你曾为找不到合适的素材而苦恼&#xff0c;那么今天就让我为你介绍几个能够快速丰富你视频内容的素材平台。无论是为了搬运视频还是寻找灵感&#xff0c;下面这些网站都将是你的强力助手。特别地&…

【软件测试】6.设计测试用例的设计方法

目录 1.基于需求的设计方法 2.具体的设计方法 2.1等价类 2.2边界值 2.3正交法 2.4判定表法 2.5场景法 2.6 错误猜测法 1.基于需求的设计方法 基于需求的设计方法也是总的设计测试用例的方法&#xff0c;在工作中&#xff0c;我们需要参考需求文档/产品规格说明书来设计…

MySQL—函数(介绍)—字符串函数(基础)

一、引言 提到函数&#xff0c;在SQL分类中DQL语句中有一个聚合函数&#xff0c;如COUNT()、SUM()、MAX()等等。这些都是一些常见的聚合函数&#xff0c;而聚合函数只是函数的一种&#xff0c;接下来会详细的学习和介绍一下函数的应用场景和以及 mysql 当中文件的函数有哪些。 …

(ISPRS,2023)RS-CLIP: 基于对比视觉-语言监督的zero-shot遥感场景分类

文章目录 相关资料摘要引言方法CLIP回顾伪标签生成课程学习策略 实验数据集不同文本提示失败案例分析课程学习zero-shot分类 相关资料 论文&#xff1a;RS-CLIP: Zero shot remote sensing scene classification via contrastive vision-language supervision 摘要 零样本遥…

【GeoServer系列】——安装与发布shapefile数据

GeoServer是一个基于java的服务器&#xff0c;它允许用户查看和编辑地理空间数据。使用OGC制定的开放标准&#xff0c;GeoServer在地图创建和数据共享方面具有极大的灵活性。 功能概述&#xff1a; Open and Share Your Spatial Data GeoServer允许您向世界显示您的空间信息。G…

【STL】C++ queue队列(包含优先级队列) 基本使用

目录 一 queue 1 常见构造 1 空容器构造函数 2. 使用指定容器构造 3 拷贝构造函数 2 empty 3 size 4 front && back 5 push && pop 6 emplace 7 swap 二 优先级队列( priority_queue) 1 常见构造 2 其他操作 3 大堆和小堆 1. 大小堆切换 2 自…

scGPT实验解读

本篇内容为发表在Nature Methods上的scGPT的部分实验内容 来自&#xff1a;scGPT: toward building a foundation model for single-cell multi-omics using generative AI, Nature Methods, 2024 目录 scGPT揭示特定细胞状态的基因网络缩放法则和迁移学习中的上下文效应 scGP…

寄存器、缓存、内存(虚拟、物理地址)、DDR、RAM的关系

寄存器、缓存、内存、DDR、RAM的关系 1. 主要概念内部存储器&#xff1a;2.1 寄存器&#xff0c;register2.2 主存储器&#xff0c;内存&#xff0c;memory2.3 缓存&#xff0c;高速缓冲存储器&#xff0c;cache 外部存储器2.4 快闪存储器&#xff0c;闪存&#xff0c;flash Me…

AI图书推荐:使用GPT-4和ChatGPT开发AI应用APP

这本书是面向想要学习如何使用大型语言模型构建应用程序的 Python 开发人员的全面指南。作者 Olivier Caelen 和 Marie-Alice Blete 涵盖了 GPT-4 和 ChatGPT 的主要特征和好处&#xff0c;并解释了它们的工作原理。您还将获得使用 GPT-4 和 ChatGPT Python 库开发应用程序的逐…

多台相同IP产品如何组网?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

Unity协程详解

什么是协程 协程&#xff0c;即Coroutine&#xff08;协同程序&#xff09;&#xff0c;就是开启一段和主程序异步执行的逻辑处理&#xff0c;什么是异步执行&#xff0c;异步执行是指程序的执行并不是按照从上往下执行。如果我们学过c语言&#xff0c;我们应该知道&#xff0…

【零基础AI】Windows下最易懂的Cuda+cudnn+PyTorch配置教程

【零基础AI】最易懂的Windows下CUDAcuDNNPyTorch配置教程 本文面向零基础的AI初学者以及迁移DL开发环境的相关人员&#xff0c;旨在通过最直观、最简洁的一条龙式图文配置教程&#xff0c;最大程度地降低学习门槛与迁移环境的成本。在配置工作开始之前&#xff0c;请务必检查确…

U-boot、linux内核、根文件系统移植以及程序

终于这几天把这个移植的流程过了一遍&#xff0c;所以特此回来总结。 U-boot移植 首先是U-boot移植。Linux 系统要启动就必须需要一个 bootloader 程序&#xff0c;也就说芯片上电以后先运行一段bootloader 程序。这段bootloader程序会先初始化DDR等外设&#xff0c;然后将Li…