归并排序(非递归实现) 计数排序

上一期我们说了归并排序的递归是如何实现的,但是递归如果层次太多的话容易栈溢出,所以我们还需要掌握非递归的实现,但是我们非递归需要如何实现?

下面我们就来看一下非递归的实现

归并排序的非递归实现他并不需要栈队列这些东西来辅助实现非递归6718d7d9215645ec8df606c7609112ce.png,可以直接改为循环

这里我就直接说了,如果我们想改循环的话,我们可以想一下如何改成循环,我们想一下递归

递归的时候是先分为一个一个的数值,然后两个值进行比较,然后归并,然后就依次归并,那么我们想要循环,我们可不可以直接先让两个两个数字进行比较,所以我们这里可以直接让两个两个数字比较

就像这样

fea4aa447a9e4c4ba489e5644ea224e7.png

我们可以直接让两个两个数字进行比较,所以等一趟循环比较结束后

 6fec688b6e284129ac1ca54c849d4186.png

这一趟结束后,就两个两个已经归并结束,所以这时候我们就四个四个一起归并

ba0227c796ca4bae85a2412dca83fcc6.png 

就像这样,我们把2 4和1 6认为是两组数据,然后就让他们进行归并,同时后面的两组数据也是相同的

最后就是这样

79b765cd118b4bd2817d6ea4dd7d1583.png 

然后我们就让每四个为一组数据

8f52dff74f994067bc4e53ed72ded634.png 

就是这样,然后继续让他们进行归并

a3c19603d6bb44b299181ae21fbcbcf9.png 

最后就归并结束

好了这个就是思想,那么我们应该如何实现呢?

我们先浅浅的看一下代码

 e3ef1d9742354604901b47f2d9f906e0.png

我们还是需要一个临时数组的,用来存放归并时的临时数据,所以这时候我们就可以,定义一个gap,让gap从1开始变化,每一次都增加2,这样我们就可以实现,刚开始是一个一个排序,然后就是每两个两个排序,然后就是四个四个,知道gap大于n(整个数组的数据个数)就结束了

所以我们就可以实现归并

所以下面的代码就是这样 

7b6b3a35847b420ca714e47dbd016272.png

 

下面就是定义一个j初始为i,然后进行比较然后拷贝,这样就可以 ,等每一次归并结束后,把tmp里面的数据拷贝回原数组就可以了

但是真的是这样就结束了吗?

其实并不是,我们可以想一下,如果我们里面的数据并不是2的指数倍的时候是什么样子的,我们可以仔细想一下,我们此时的gap每一次都以2倍增加,所以我们肯定会有越界,所以我们这时候就需要对我们定义的begin1和end1以及begin2和end2进行调整

我们可以想一下

但是我们这四个变量都需要调整吗?

d8a442e72dc24811b05f5272fd16254e.png

这里我们看到我们这四个变量,那么我们四个变量都会越界吗?如果有哪些越界了我们需要调整呢?哪些越界之后我们还需要归并吗?哪些越界之后我们就不需要归并了,我们想一下

我们的begin1会不会越界?

显然不会的,因为我们的begin1每一次都是i而我们的i又是小于n的所以我们的begin1不会越界,但是我们的end1会越界吗?会的

所以,既然我们的end1都会越界,所以后面的两个也当然是会越界的,而我们这三个变量越界后的处理也当然是不一样的

如果我们的end1越界了,那么我们还需要对该数组进行归并吗?

我们想一下,如果我们的end1越界,说明我们只有一组甚至是一组都不到的数据,所以我们只有一组数据当然是不用归并的,那么我们的begin2越界呢?

如果我们的begin2越界,也说明我们只有一组数据,也是不用归并的,所以我们这里就可以直接不归并,那么我们的end2越界呢?

我们的end2越界,说明我们现在至少有一组多的数据,所以我们这里是需要归并的,那么我们应该怎么样调整呢?

我们可以看一下

29e06dd58d8748d19c7149f9731535bf.png 

和我们上面所说的一样,我们如果是end1或者begin2越界的话,说明我们只有一组数据,并不需要归并,如果我们的end2越界,说明我们有一组多的数据,是需要归并的,所以我们只需要把end2调整为不会越界就可以了

下面我们看一下整体的代码

4b8dd97885b74552b04f8462b40f1651.png 

其实上面只是一种写发,这种写法是每归并一次就拷贝一次,还有一种是一组全部归并好后,才进行拷贝,其实两种写法都是差不多的,这里把下面的一种也贴出来

d7a41ec963af41e485520fed40b2c069.png 

 OK 这就是归并排序的非递归,下面讲一下计数排序

我们前面说的几种排序都是比较排序,而计数排序是非比较排序

下面我们就来看一下计数排序,这里就直接说计数排序的思想以及用途了

这里的计数排序是特殊情况下使用的,可是他适用于什么情况呢?他适用于数字比较集中的排序,如果是这种情况他的时间复杂度特别好,已经能达到O(N),所以他在特定时候是特别厉害的

这里就说一下如何实现

计数排序他可以开一段数组,这段数组用来映射,就像这样

544638ada053423195f9cf113904bc83.png

如果我们是这一组数据的话,那么我们如何排序呢?

这里直接说思想,我们先开一段数组,然后把他里面初始化为0,然后这里把上面的一组数据依次遍历一遍,然后使用映射,下面看图片

 47e053af67c4485cb575d0194e6c244e.png

这里首先是0,然后再0位置++,然后遍历到下一个数字,

c5dcfcb8f6d84092bb6bc607aa57bf26.png

然后到5的位置++,就这样依次下去

327a135d0eb944b488745c49ccdcd0c4.png 

263bf89df5184be68a76fd7a614b96df.png 

然后是这样,知道这一组数字结束

但是这样是有缺点的

我们看图片

3cf32acff9e74214b1ab1d8f52696059.png 

 如果是这一组数据的话,那么我们可以看到,我们这一组数据会集中于后面

所以1e10b7d8387840aba126d7c6e418721a.png

 我们只能使用后面的这一组空间

ac64f0677669498dbf41802cc3d51285.png

 但是我们前面的这么多空间都会浪费掉,所以我们需要想一个解决办法

绝对映射会浪费太多的空间,那么我们就可以使用相对映射

我们可以这样

4f218efaacc44d21bb1c797c214cb974.png

我们就可以找到里面的最大值,和最小值,然后算出他们的差,然后我们就只需要开差距大小的空间就可以了,我们在计数排序的时候只需要让每个数字-掉最小值就可以了,就像这样

ed65254153444f37be9dd3490bf794af.png 

就是这样,所以我们现在可以直接看代码了

a33f43e7250f452f9bf3b71ce63c266e.png 

我们看明白思想之后看代码应该就是很容易了,所以这里也就不多解释

今天结束

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

day10_oop

今日内容 零、 复习昨日 一、面向对象的概念 二、面向对象编程 三、内存图 零、 复习昨日 晨考复习… 一、作业 package com.qf.homework;import java.util.Arrays;/*** --- 天道酬勤 ---** author QiuShiju* desc* ----------------* 引用数据类型的默认初始值null*/ public …

Redis数据备份与恢复

Redis数据备份与恢复 文章目录Redis数据备份与恢复1. Redis备份的方式2. RDB持久化2.1 什么是RDB?2.2 Fork操作2.3 save VS bgsave2.4 关于RDB备份的一些配置项2.5 RDB的备份与恢复2.6 RDB的自动触发2.7 RDB的优势与劣势3. AOF持久化3.1 什么是AOF?3.2 A…

ASP一个简单的网上教务系统模型的设计与实现

对于一个学校来说,大量教师信息,学生信息管理,学生成绩管理,基本数据的维护都难于通过传统的方法进行管理:这就迫切需要利用计算机技术来帮助学校管理者处理这些日常管理。本系统正是为了简化教学任务的管理&#xff0…

Python爬虫之多线程加快爬取速度

之前我们学习了动态翻页我们实现了网页的动态的分页,此时我们可以爬取所有的公开信息了,经过几十个小时的不懈努力,一共获取了 16万 条数据,但是软件的效率实在是有点低了,看了下获取 10 万条数据的时间超过了 56 个小…

Vue——组件基础

目录 定义一个组件​ 使用组件​ 传递 props​ 监听事件​ 通过插槽来分配内容​ 动态组件​ DOM 模板解析注意事项​ 大小写区分​ 闭合标签​ 元素位置限制​ 组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应…

如何用 YonBuilder 构建线索管理应用

加速企业数智营销:如何用 YonBuilder 构建线索管理应用 如何用 YonBuilder 低代码开发线索管理应用? 线索管理是指通过各种渠道收集、筛选、打分、分配、跟进和培育潜在客户的信息,以便将其转化为成交客户的过程。 通过数智化手段实现良好…

00后整顿职场,我直呼太卷了....

内卷的来源 内卷最早的“出处”是几张名校学霸的图片。 大学生们刷爆朋友圈的几张“内卷”图片是这样的:有的人骑在自行车上看书,有的人宿舍床上铺满了一摞摞的书,有的人甚至边骑车边端着电脑写论文。这些图片最早在清华北大的学霸之间流传。…

C++学习从基础到高阶(基于黑马程序员教程)

视频链接:黑马程序员匠心之作|C教程从0到1入门编程,学习编程不再难(52个小时) C语言中文网:http://c.biancheng.net/cplus/ Visual Studio 2022 下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/ Visu…

JavaWeb - Web网站的组成,工作流程以及开发模式

一. Web Web:全球广域网,也称玩万维网(www Wrold Wide Web),就是能够通过浏览器访问的网站学习Web开发,其实就是要使用Java这门语言来开发这样的Web网站,这也是现在Java语言最主流的企业级应用方式。使用Java语言开发…

PERSIANN 降雨数据使用教程

一、前言PERSIANN,“使用人工神经网络从遥感信息中估算降水”,是一种基于卫星的降水检索算法,可提供近乎实时的降雨信息。该算法使用来自全球地球同步卫星的红外 (IR) 卫星数据作为降水信息的主要来源。 红外图像的降水基于云顶温度和降水率之…

一位腾讯在职7年测试工程师的心声...

作为一个在腾讯工作7年的测试工程师,今天就来聊聊腾讯工作压力到底从何而来。 压力的开始:时间回到7年前,我人生中的第一份实习工作,是在腾讯公司做一个自动化测试工程师。当时的我可谓意气风发,想要大干一场&#xf…

工厂模式白话 - 3种都有哦

前言 工厂模式(Factory Pattern)里所谓的“工厂”和现实生活中的工厂一样 主要作用都是生产产品 像食品厂、服装厂、汽车厂生产吃的、穿的、开的 设计模式里的工厂则是生产对象 划分 工厂模式可分为简单工厂、工厂方法、抽象工厂3种 有啥不同呢&a…

PyTorch笔记

Tensor torch中的Tensor是一种数据结构,使用上与Python的list、numpy的array、ndarray等数据结构类似,可以当成一个多维数组来用。 数学上对张量有特定定义,但通常理解为多维数组即可。 生成Tensor:torch包中提供了直接生成Tens…

【微信小程序】初识微信小程序组件

作者简介:一名C站萌新,前来进行小程序的前进之路博主主页:大熊李子🐻 一、组件的创建与引用 1.1 创建组件 在项目的根目录中,鼠标右键,创建 components -> test 文件夹在新建的 components -> test…

十分钟验证一个轻量化车联网解决方案

智能网联汽车在车联网的应用上,通常是以智能传感器、物联网、GIS技术为基础,结合大数据、人工智能技术,通过OT(Operation tecnology)和IT(information tecnology)融合的方式,实现智能…

2.3 连续性随机变量

思维导图: 学习目标: 我会按照以下步骤学习连续型随机变量: 复习概率论的基础知识,包括概率、期望、方差等概念和公式,以及离散型随机变量的概率分布函数和概率质量函数的概念和性质。 学习连续型随机变量的概念和性…

学生信息管理系统(student information manage system, SIMS)

一、前言 本项目为学生信息管理系统,使用C语言编写。 ★★★项目详见本人gitee仓库,地址 https://gitee.com/omnipotent-brother/student-information-manage-system.git ★★★ 二、项目介绍 开发环境: 基于windows 11系统下的Visual Studio…

YC-A11(原创)基于springboot,vue网上商城

绪论 课题的开发背景 随着计算机和网络的快速发展,并且越来越普及,互联网日益成为人们收集信息常用渠道,电子商务开始流行,一种全新的理念不断形成并且快速发展,像国内电商巨头淘宝、京东、苏宁易购、唯品会等电商平台…

【JavaScript】2.JavaScript函数

JavaScript 函数 1. 函数的概念 函数&#xff1a;就是封装了一段可被重复调用执行的代码块 通过此代码块可以实现大量代码的重复使用 2. 函数的使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta na…

前馈PID控制(热交换器/反应釜温度控制)

如何利用PID进行温度控制请参看下面博客文章: 博途PID 1200/1500PLC PID_Compact比例作用权重b微分作用权重c解读(PI-D控制器 I-PD控制器)_RXXW_Dor的博客-CSDN博客很多人会问PLC自带的PID指令和我们自己设计的PID有什么区别,这个问题要看你和什么PID控制器作对比,PID负反…