我对排序算法的理解

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

我明白我的问题,就是感觉自己懂了,其实,还是不懂。只要逻辑乱一次,就基本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.rhkb.cn/news/74378.html

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

相关文章

【Mybatis】Mybatis架构简介

文章目录 1.整体架构图2. 基础支撑层2.1 类型转换模块2.2 日志模块2.3 反射工具模块2.4 Binding 模块2.5 数据源模块2.6缓存模块2.7 解析器模块2.8 事务管理模块 3. 核心处理层3.1 配置解析3.2 SQL 解析与 scripting 模块3.3 SQL 执行3.4 插件 4. 接口层 1.整体架构图 MyBatis…

Redis 数据库高可用

Redis 数据库的高可用 一.Redis 数据库的持久化 1.Redis 高可用概念 &#xff08;1&#xff09;在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。 …

2023年第四届“华数杯”数学建模思路 - 案例:随机森林

## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林&#xff1f; 随机森林属于 集成学习 中的 Bagging&#xff08;Bootstrap AGgregation 的简称&#xff09; 方法。如果用图来表示他们之…

【微信支付V3】

微信支付V3 微信支付V3 开发文档&#xff1a; https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/index.shtml 1. 查看文档 使用微信提供的SDK&#xff0c;在文档中进入SDK 2. 开发 1. 添加jar包 <dependency><groupId>com.github.wechatpay-apiv3<…

使用adb通过电脑给安卓设备安装apk文件

最近碰到要在开发板上安装软件的问题&#xff0c;由于是开发板上的安卓系统没有解析apk文件的工具&#xff0c;所以无法通过直接打开apk文件来安装软件。因此查询各种资料后发现可以使用adb工具&#xff0c;这样一来可以在电脑上给安卓设备安装软件。 ADB 就是连接 Android 手…

Java进阶——数据结构与算法之哈希表与树的入门小结(四)

文章大纲 引言一、哈希表1、哈希表概述2、哈希表的基本设计思想3、JDK中的哈希表的设计思想概述 二、树1、树的概述2、树的特点3、树的相关术语4、树的存储结构4.1、双亲表示法4.2、孩子兄弟表示法&#xff1a;4.3、孩子表示法&#xff1a;4.4、双亲孩子表示法 三、二叉树1、二…

SAM在医学图像分割的一些研究(Segment Anything Model for Medical Images?(2023))

使用预训练模型通过两种主要模式进行分割&#xff0c;包括自动一切和手动提示(例如&#xff0c;点和框)。SAM在各种自然图像分割任务上取得了令人印象深刻的效果。然而&#xff0c;由于医学图像的形态复杂、解剖结构精细、物体边界不确定和复杂、物体尺度大&#xff0c;使得医学…

【第一阶段】kotlin的when表达式

1.Java 的if /when是语句 kotlin的if/when是表达式&#xff0c;表达式是有返回值的 java中void是个关键字&#xff0c;Unit在kotlin中是个类 2.当使用when语句的时候必须有一个不满足的值即else: fun main() {var week:Int5val info when(week){1->"今天是星期一"…

【iOS】—— UIKit相关问题

文章目录 UIKit常用的UIKit组件懒加载的优势 CALayer和UIView区别关系 UITableViewUITableView遵循的两个delegate以及必须实现的方法上述四个必须实现方法执行顺序其他方法的执行顺序&#xff1a; UICollectionView和UITableView的区别UICollectionViewFlowLayout和UICollecti…

em3288 linux_4.19 第一次烧写无法进入内核的情况

1. 情况一&#xff1a; /DDR Version 1.11 20210818 In SRX Channel a: DDR3 400MHz Bus Width32 Col10 Bank8 Row15 CS1 Die Bus-Width16 Size1024MB Channel b: DDR3 400MHz Bus Width32 Col10 Bank8 Row15 CS1 Die Bus-Width16 Size1024MB OUT Boot1 Release Time: Jul 22 2…

Jenkins插件管理切换国内源地址

一、替换国内插件下载地址 选择系统管理–>插件管理–> Available Plugins 并等待页面完全加载完成、这样做是为了把jenkins官方的插件列表下载到本地、接着修改地址文件、替换为国内插件地址 进入插件文件目录 cd /var/lib/jenkins/updatesdefault.json 为插件源地址…

STM32 LWIP UDP 一对一 一对多发送

STM32 LWIP UDP通信 前言设置 IP 地址UDP函数配置实验结果单播发送&#xff0c;一对一发送广播发送&#xff0c;一对多发送 可能遇到的问题总结 前言 之前没有接触过网络的通信&#xff0c;工作需要 UDP 接收和发送通信&#xff0c;在网上没有找到一对一、一对多的相关例程&am…

正则表达式在格式校验中的应用以及包装类的重要性

文章目录 正则表达式&#xff1a;做格式校验包装类&#xff1a;在基本数据类型与引用数据类型间的桥梁总结 在现代IT技术岗位的面试中&#xff0c;掌握正则表达式的应用以及理解包装类的重要性是非常有益的。这篇博客将围绕这两个主题展开&#xff0c;帮助读者更好地面对面试挑…

IIC子系统-实现si7006温湿度传感器采集温湿度功能

1.将IIC核心层和总线驱动层配置进内核 *********************配置核心层*************************1.找到核心层代码目录&#xff1a;内核顶层目录/drivers/i2c2. 内核顶层目录执行make menuconfig3. > Device Drivers > I2C support ->-*-I2C support4.保存退出***…

数据预处理matlab

matlab数据的获取、预处理、统计、可视化、降维 数据的预处理 - MATLAB & Simulink - MathWorks 中国https://ww2.mathworks.cn/help/matlab/preprocessing-data.html 一、数据的获取 1.1 从Excel中获取 使用readtable() 例1&#xff1a; 使用spreadsheetImportOption…

端口映射教程vs快解析内网穿透

随着社会信息化的发展&#xff0c;很多人都开始关注网络问题&#xff0c;掌握一些基础的网络知识是非常有必要的。其中&#xff0c;端口映射作为一项重要的技术&#xff0c;在网络通信中起到了至关重要的作用。 端口映射在现实生活中有着广泛的应用。如果你是一位游戏爱好者&a…

极狐GitLab 全新「价值流仪表盘」使用指南

本文来源&#xff1a;about.gitlab.com 作者&#xff1a;Haim Snir 译者&#xff1a;极狐(GitLab) 市场部内容团队 GitLab / 极狐GitLab 价值流仪表盘的使用相对简单&#xff0c;这种可以定制化的仪表盘能够让决策者识别数字化转型进程中的趋势及机遇。 如果你已经在用 GitLab…

NGZORRO:动态表单/模型驱动 的相关问题

官网的demo的[nzFor]"control.controlInstance"&#xff0c;似乎是靠[formControlName]"control.controlInstance"来关联的。 <form nz-form [formGroup]"validateForm" (ngSubmit)"submitForm()"><nz-form-item *ngFor&quo…

day50-Insect Catch Game(捉虫游戏)

50 天学习 50 个项目 - HTMLCSS and JavaScript day50-Insect Catch Game&#xff08;捉虫游戏&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport"…

【MySQL】数据库基本使用

文章目录 一、数据库介绍二、数据库使用2.1 登录MySQL2.2 基本使用2.2.1 显示当前 MySQL 实例中所有的数据库列表2.2.2 创建数据库2.2.3 创建数据库表2.2.4 在表中插入数据2.2.5 在表中查询数据 三、服务器、数据库、表之间的关系四、SQL语句分类五、存储引擎 一、数据库介绍 …