我对排序算法的理解

排序算法一直是一个很困惑我的问题,早在刚开始接触 数据结构的时候,这个地方就很让我不解。就是那种,总是感觉少了些什么的感觉。一开始,重新来过,认真来学习这一部分,也总是学着学着就把概念记住了。过了一会,让我重新来写这些算法,又变得不会。

我明白我的问题,就是感觉自己懂了,其实,还是不懂。只要逻辑乱一次,就基本oh my gad了。

然后我就看视频,找一些算法的更通俗易懂的一些理解。还是感觉差了些什么。

不过,最后还是找到一些自己的理解方式。

做关于排序的算法题:

首先你要明白它是怎么排序的。以选择排序为例:

 ok,我们知道选择排序就是每一轮寻找一个最小的值。

继续:看这个选择排序的过程,共进行了6轮、每一轮又进行了多少次比较?

这个问题,就是一个嵌套循环的问题:

写出这个循环的嵌套才能进行下一步:口诀就是外层循环表示行,内层循环表示列。我看了很对其它的解释,个人感觉所有嵌套循环,记住这个特点就足够了。

回到这个算法:

  //很明显,外层循环有6轮,那么外层循环的判定就是arr.length-1。这个很简单。//表示的范围就是【0~6】
for(int i=0;i<arr.length-1;i++){//内层循环表示列。for(){}
}

重点来了,怎么写内循环的问题!!!

这里一定要学好,因为不同的排序算法,基本上它的内循环都不同。但是它们都会存在一定的规律和共性。

我们在看这个算法。

每一轮都是找最小值。第一轮,从7个元素找;第二轮从6个元素里面找;第三轮就是5个。

那么内循环表示列:就相当于,第一轮7列(7个元素),第二轮6列(除第一个元素之外。)

for(int i=0;i<arr.length-1;i++){//内层循环表示列。//它的范围就是:0~6(7列)、1~6(除了第一个元素0之外的6列)、2~6(5列)for(int j=i;j<arr.length-1;j++){}
}

然后,循环嵌套的问题我们就解决了,基本上,选择排序算法我们的问题就解决一半了!

我们再来看不同排序算法间嵌套循环的共性:以插入排序的嵌套循环为例。

你可以自己尝试一下,写出这个循环的嵌套语句:

//6行,就是外循环6次
for(int i=0;i<arr.length-1;i++){//内循环,观察这个算法的要求。//第一行:从第二列开始和前一个比较。//第二行:从第三列和前面两个比较。//第三行:就是第四个,和前面三个比较。这里不太好画图,自己画一下图,就是一种滑坡的形状。//那么初始条件,我们可以设为i+1。(从第二列开始)。那么判定条件是什么呢?//第一次判定只比较一次,第二次判定比较两次,第三次就是比较三次。那就是j>0咯。//它的范围就是:1(和0比较)、2~1(和0,1比较)、3~1(和0,1,2比较)for(int j=i+1;j>0;j++){}
}

 这个算法和选择排序算法的嵌套循环的共性是什么呢?

重点在内循环。

我的理解是:

   在外循环 i表示行数,内循环 j表示列的前提下。那么一定会在内循环的初始条件或判定条件用到i,而且有且只能用到一次。要么i用在初始条件,要么用在判定条件。

比如:看选择排序的算法:
内循环:for(int j=i;j<arr.length-1;j++)
i用在初始条件。插入排序的算法:
内循环:for(int j=i+1;j>0;j--)
i用在初始条件。冒泡排序:这个很简单,就是从第一个往后面比较,小的往前,大的往后。
内循环:for(int j=0;j<arr.length-i-i;j++)
i用在判定条件。上面三个算法的外循环都是一样的。

我之前做这个算法题时,就这样写过:

错误的写法,选择排序:
for(int j=i;j<arr.length-i;j++)如果是这样写,那么它的范围就是:
0~6(第一轮比较和之前是一样的比较的比较7次)
1~5(这里只比较了5次)
2~4
3~3(到这里就结束了,不会运行。)
造成的问题就是:只有效比较了三行(也不是很有效,只有效比较了第一行)。后面三行就根本不会比较,只打印出来。
而我们需要比较是6行。和i的关系是紧密联系的!
故此:我得出结论,在排序算法或者嵌套循环有关,在内循环里面如果要使用i。那么只能使用一次。

故此:我得出结论,在排序算法或者嵌套循环有关,在内循环里面如果要使用i。那么只能使用一次。
 

欧克,关于循环嵌套的问题就到这。想自己训练一下,可以尝试打印9*9乘法口诀表,或者打印三角形的形状。这些都运用了嵌套循环。

在来看算法问题:

以插入排序的算法为例:

它的核心就是从第二个元素开始往前比较。你要从内存空间的角度去思考。这里没有涉及堆和栈,堆和栈也很重要,不过在面向对象的时候才会学习堆和栈的空间变化。

它的空间变化:只以前四个数为例。

原数据:56 、34、45、12、67、52、4
从算法是赋值的角度变化:
两两比较,小的排前面。在算法角度就是,两个交换了位置。具体变化:56、34、45、12
第一行:34 34 45 12 ~   temp=56
               34 56 45 12 
 第二行:34 45 45 12  ~  temp=56
                34 45 56 12 
 第三行:34 45 12 12  ~temp=56
                34 45 12 56 
                34 12 12 56    temp=45 
                34 12 45 56 
                12 12 45 56    temp=34
                12 34 45 56 

我们第三行的最终比较结果就是12、34、45、56、67、52、4。

那么就可以写算法了:

//外循环6行
for(int i=0;i<arr.length-1;i++){//内循环for(int j=i+1;j>0;j++){if(arr[j] < arr[j-1]){   //看上面的规律,是不是两两比较。然后小的排前面。temp = arr[j];arr[j-1] = arr[j];arr[i] = temp;}}Systemo.out.println(Arrays.toString(arr));  //打印每一行的结果
}

算法的主要问题在哪,主要就是j、j+1或者j-1这样的判断。不知道怎么用,会不会出事。这就是第二个困扰的问题。

这个问题解决了,基本上算法排序就比较容易理解了。

其实,关于j 、j+1这样的用法和嵌套循环也很类似。就是j+1的范围不能超过原来数组的长度。j-1不能小于原来数组的长度。超出了,基本上这个算法就出错了。

建议:打草稿咯,像我上面那个例子一样,去画一下内存的变化。就不会出错。

这里,关于插入排序的算法就很有意思了,它的核心算法从每一轮找最小的值,这个最小的值不能通过两两比较交换位置。(透露一下:通过比较返回索引值。直到找到最小的值所在索引,然后和第一个数进行交换。)

选择排序核心算法:

for(int i=0;i<arr.length-1;i++){//内层循环表示列。//它的范围就是:0~6(7列)、1~6(除了第一个元素0之外的6列)、2~6(5列)index=i;for(int j=i;j<arr.length-1;j++){if(arr[index] > arr[j+1]){index=j+1;       }}temp = arr[index];   //将第一个位置和找到索引最小的元素进行交换arr[i] = arr[index];arr[index] = temp;System.out.println(Arrays.toString(arr));
}

选择排序的算法去画画它的内存变化吧。

之后我会不停添加其它的算法来验证我的理解和猜想。暂时先写到这了。

补充:嵌套循环还有一个条件,在循环用的一个数组的情况下,内循环的范围不能超过外循环,外循环的范围不能超过原数组。

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

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

相关文章

案例|会展大数据服务系统 智能服务体系建设实践

根据相关的市场调查发现在国内进行的2000多个会展项目中&#xff0c;仅有15%的项目能够提供相关主题网站基本业务和服务&#xff0c;且提供的服务并不能够满足会展各方的应用&#xff0c;剩余的大部门会展项目信息系统构建的不够完善、技术性差、应用复杂等&#xff0c;甚至提供…

三、JVM-如何判断对象已死问题

内存模型以及如何判定对象已死问题 体验与验证 2.4.5.1 使用visualvm visualgc插件下载链接 &#xff1a;https://visualvm.github.io/pluginscenters.html 选择对应JDK版本链接—>Tools—>Visual GC 若上述链接找不到合适的&#xff0c;大家也可以自己在网上下载对应…

Hive巡检脚本

Hive巡检脚本的示例&#xff1a; #!/bin/bash# 设置Hive连接信息 HIVE_HOST"your_hive_host" HIVE_PORT"your_hive_port" HIVE_USER"your_hive_username" HIVE_PASSWORD"your_hive_password"# 设置巡检结果输出文件路径 OUTPUT_FILE&…

服务器的shell脚本

shell脚本语句可以执行linux的操作语句。 linux相当于网页&#xff0c;shell相当于java。可以解释编写执行逻辑。 shell的开头以&#xff1a;#!bin/sh 定义解析方式&#xff0c;不同的linuxe内核解释方式不同。大多数内核支持sh&#xff08;bash&#xff09;方式。 执行sh文件可…

输入筛选框搜索

文章目录 输入筛选框实现效果图需求前端工具版本添加依赖main.js导入依赖 代码 后端代码对应 sql对应 mapper.xml 文件的动态 sql 输入筛选框实现 效果图 需求 通过筛选框&#xff0c;选择公司&#xff0c;传入后端&#xff0c;后端根据公司名称去文章的内容中进行模糊查询 …

照片回收站是什么?恢复照片就靠这3招!

“我电脑里本来保存了很多照片&#xff0c;但我不小心给删除了&#xff0c;还能恢复吗&#xff1f;由于本人是个电脑新手&#xff0c;求一些简单的方法。感谢&#xff01;” 在照片拍摄后&#xff0c;很多朋友可能会选择在电脑上对照片进行保存。但是由于各种原因&#xff0c;电…

Simulink仿真模块-Signal Builder

目录 说明 实例 Signal Builder是创建和生成可交替的具有分段线性波形的信号组。 在仿真库中的位置为:Simulink / Sources说明 Signal Builder 模块允许创建可交替的分段线性信号源组,并在模型中使用。可以快速将信号组切换入模型或切换出模型,以便于测试。在 Signal Buil…

Linux【网络编程】之深入理解TCP协议

Linux【网络编程】之深入理解TCP协议 TCP协议TCP协议段格式4位首部长度---TCP报头长度信息 TCP可靠性&#xff08;确认应答&#xff09;&& 提高传输效率确认应答(ACK)机制32位序号与32为确认序号 16位窗口大小---自己接收缓冲区剩余空间的大小16位紧急指针---紧急数据处…

js 视频水印去除

参考文档&#xff1a;http://txapi.cn/api 收费 识别要解析的类型&#xff08;需要收费&#xff09; const axios require(axios) class Parse{// 初始化方法constructor() {this.token "Z1QljZOZiT4NTG" // token// 请求地址数组对象this.req_urls {dy: "…

无涯教程-Lua - 文件I/O

I/O库用于在Lua中读取和处理文件。 Lua中有两种文件操作&#xff0c;即隐式(Implicit)和显式(Explicit)操作。 对于以下示例&#xff0c;无涯教程将使用例文件test.lua&#xff0c;如下所示。 -- sample test.lua -- sample2 test.lua 一个简单的文件打开操作使用以下语句。…

Unity3D坐标与UI坐标转化差别过大

在UI Canvas的Render Mode模式是Screen Space-Camera模式极其容易3D坐标值转UI坐标出错。 **具体原因是&#xff1a;**Canvas的Rect Transform锁定&#xff0c;其Scale的倍数值不是1&#xff0c;所以导致从3D的坐标数值转换成UI坐标时就会出现问题。 正确做法&#xff1a; 1、 …

ChatGPT 是如何工作的:从预训练到 RLHF

欢迎来到人工智能的未来:生成式人工智能!您是否想知道机器如何学习理解人类语言并做出相应的反应?让我们来看看ChatGPT ——OpenAI 开发的革命性语言模型。凭借其突破性的 GPT-3.5 架构,ChatGPT 席卷了世界,改变了我们与机器通信的方式,并为人机交互开辟了无限可能。随着…

改进的智能优化算法定性分析:种群多样性分析(Analysis of the population diversity)

目录 一、智能优化算法改进种群多样性分析 二、GWO与IGWO种群多样性对比 三、GWO与改进的GWO1种群多样性分析 四、代码获取 一、智能优化算法改进种群多样性分析 为了验证所提出的IDMO中种群多样性的丰富性&#xff0c;我们使用下式计算本节中的种群多样性。这个式…

Java并发系列之四:重中之重AQS

上一期我们介绍了乐观锁&#xff0c;而乐观锁的本质即是CAS&#xff0c;操作系统提供了支持CAS修改内存值的原子指令&#xff0c;所以乐观锁得以实现。从软件工程的角度去看&#xff0c;虽然底层已经通过CAS实现了乐观锁&#xff0c;Java的底层已经在Unsafe这个类中封装了compa…

【BASH】回顾与知识点梳理(三)

【BASH】回顾与知识点梳理 三 三. 命令别名与历史命令3.1 命令别名设定&#xff1a; alias, unalias3.2 历史命令&#xff1a;history同一账号同时多次登入的 history 写入问题无法记录时间 三. 命令别名与历史命令 我们知道在早期的 DOS 年代&#xff0c;清除屏幕上的信息可以…

《Java极简设计模式》第02章:抽象工厂模式(AbstractFactoty)

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章汇总&#xff1a;https://binghe.gitcode.host/md/all/all.html 源码地址&#xff1a;https://github.com/binghe001/java-simple-design-patterns/tree/master/j…

3.病人排队

【题目】 病人登记看病&#xff0c;编写一个程序&#xff0c;将登记的病人按照以下原则排出看病的先后顺序&#xff1a; 老年人&#xff08;年龄 > 60岁&#xff09;比非老年人优先看病。 老年人按年龄从大到小的顺序看病&#xff0c;年龄相同的按登记的先后顺序排序。 非…

Cirno‘s Perfect Equation Class 2023牛客暑期多校训练营5 D

登录—专业IT笔试面试备考平台_牛客网 题目大意&#xff1a;有q次询问&#xff0c;每次给出三个整数k&#xff0c;c&#xff0c;n&#xff0c;求有多少满足条件的数对&#xff08;a&#xff0c;b&#xff09;满足kabc且c是b的倍数&#xff0c;且gcd(a,b)>n 1<q<100;…

Redis实现延时队列

缓存队列延时向接口报工&#xff0c;并支持多实例部署。 引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-data</artifactId><version>3.17.4</version> </dependency> 注入RedisClient …

flask中实现restful-api

flask中实现restful-api 举例&#xff0c;我们可以创建一个用于管理任务&#xff08;Task&#xff09;的API。在这个例子中&#xff0c;我们将有以下API&#xff1a; GET /tasks: 获取所有任务POST /tasks: 创建一个新的任务GET /tasks/<id>: 获取一个任务的详情PUT /t…