计算机速成课Crash Course - 14. 数据结构

今天继续计算机速成课Crash Course的系列讲解。

更多技术文章,公众号 “摸鱼IT” 锁定 -上午11点 - ,感谢大家关注、转发、点赞!

计算机速成课Crash Course - 13. 算法入门

14. 数据结构

上集讲了一些经典算法,比如给数组排序,找图的最短路径,而上集没讲的是,算法处理的数据存在内存里的格式是什么。

你肯定不想数据像 John Green 的大学宿舍一样乱,到处都是食物,衣服和纸。我们希望数据是结构化的,方便读取,因此计算机科学家发明了 "数据结构"!

上集已经介绍了一种基本数据结构:数组(Array),也叫列表(list)或向量(Vector)(在其它编程语言里)。

数组的值一个个连续存在内存里,所以不像之前,一个变量里只存一个值(比如 j = 5),我们可以把多个值存在数组变量里,为了拿出数组中某个值,我们要指定一个下标(index),大多数编程语言里,数组下标都从 0 开始,用方括号 [ ] 代表访问数组。

如果想相加数组 J 的第一个和第三个元素,把结果存在变量 a,可以写上图这样一行代码。

数组存在内存里的方式,十分易懂,为了简单,假设编译器从内存地址 1000 开始存数组,数组有7个数字,像上图一样按顺序存。

写 j[0],会去内存地址 1000,加 0 个偏移,得到地址 1000,拿值:5;如果写 j[5],会去内存地址 1000,加 5 个偏移,得到地址 1005,拿值:4。

很容易混淆 "数组中第 5 个数" 和 "数组下标为 5 的数",它们不是一回事。记住,下标 5 其实是数组中第 6 个数,因为下标是从 0 开始算的。

数组的用途广泛,所以几乎所有编程语言都自带了很多函数来处理数组。

举例,数组排序函数很常见,只需要传入数组,就会返回排序后的数组,不需要写排序算法。

数组的亲戚是字符串 (string),其实就是字母,数字,标点符号等组成的数组。

第 4 集讨论过计算机怎么存储字符,写代码时用引号括起来就行了,j = "STAN ROCKS",虽然长的不像数组,但的确是数组,幕后看起来像这样。

注意,字符串在内存里以 0 结尾,不是"字符0",是"二进制值0" ,这叫字符"null",表示字符串结尾,这个字符非常重要,如果调用 print 函数,print 在屏幕上输出字符串,会从开始位置,逐个显示到屏幕,但得知道什么时候停下来!

否则会把内存里所有东西都显示出来,0 告诉函数何时停下,因为计算机经常处理字符串,所以有很多函数专门处理字符串。

比如连接字符串的 strcat,strcat 接收两个字符串,把第二个放到第一个结尾。

我们可以用数组做一维列表,但有时想操作二维数据。比如电子表格,或屏幕上的像素,那么需要矩阵(Matrix),可以把矩阵看成数组的数组!

一个 3x3 矩阵就是一个长度为3的数组,数组里每个元素都是一个长度为3的数组,可以这样初始化。内存里是这样排列的。

为了拿一个值,需要两个下标,比如 j[2][1],告诉计算机在找数组 2 里,位置是 1 的元素,得到数字 12。

矩阵酷的地方是,不止能做 3x3 的矩阵,任何维度都行,可以做一个5维矩阵,然后这样访问 a = j[2][0][18][18][3],现在你知道了,怎么读一个 5 维矩阵。

目前我们只存过单个数字/字符,存进数组或矩阵,但有时, 把几个有关系的变量存在一起, 会很有用,比如银行账户号和余额。

多个变量打包在一起叫 结构体 (Struct),现在多个不同类型数据,可以放在一起,甚至可以做一个数组,里面放很多结构体,这些数据在内存里会自动打包在一起。

如果写 j[0],能拿到 j[0]里的结构体,然后拿银行账户和余额,存结构体的数组,和其它数组一样,创建时就有固定大小,不能动态增加大小。

还有,数组在内存中按顺序存储,在中间插入一个值很困难,但结构体可以创造更复杂的数据结构,消除这些限制。

我们来看一个结构体,叫节点(node),它存一个变量,一个指针(pointer),"指针" 是一种特殊变量,指向一个内存地址,因此得名。

用节点可以做链表(linked list),链表是一种灵活数据结构,能存很多个节点 (node),灵活性是通过每个节点指向下一个节点实现的。

假设有三个节点,在内存地址 1000,1002, 1008,隔开的原因可能是创建时间不同,它们之间有其他数据。

可以看到第一个节点,值是 7,指向地址 1008,代表下一个节点,位于内存地址 1008。

现在来到下一个节点,值是 112,指向地址 1002,如果跟着它,会看到一个值为 14 的节点,这个节点指回地址 1000,也就是第一个节点,这叫 循环链表。

但链表也可以是非循环的,最后一个指针是 0,"null",代表链表尽头,当程序员用链表时,很少看指针具体指向哪里,而是用链表的抽象模型,就像上图,更容易看懂。

数组大小需要预先定好,链表大小可以动态增减,可以创建一个新节点,通过改变指针值,把新节点插入链表,链表也很容易重新排序,两端缩减,分割,倒序等。

链表也适合上集的排序算法,因为灵活,很多复杂数据结构都用链表,最出名的是队列(queue)和栈(stack)。

"队列" 就像邮局排队,谁先来就排前面,虽然你可能只想买邮票,而前面的人要寄 23 个包裹,这叫先进先出(FIFO),说的是队列。

想象有个指针叫"邮局队列",指向链表第一个节点,第一个节点是 Hank,服务完 Hank 之后,读取 Hank 的指针,把"邮局队列"指向下一个人,这样就把 Hank "出队"(dequeue)了。

如果我们想把某人"入队"(enqueue)意思是加到队列里,要遍历整个链表到结尾,然后把结尾的指针,指向新人(Nick)。

只要稍作修改,就能用链表做栈,栈是后进先出(LIFO)。

可以把"栈"想成一堆松饼,做好一个新松饼,就堆在之前上面,吃的时候,是从最上面开始。

栈就不叫"入队""出队"了,叫"入栈"(push) "出栈"(pop)。

如果节点改一下,改成 2 个指针,就能做 树(tree),很多算法用了 "树" 这种数据结构,同样,程序员很少看指针的具体值,而是把"树"抽象成这样:最高的节点叫"根节点"(root),"根节点"下的所有节点,都叫"子节点"(children)。

任何子节点的直属上层节点,叫"母节点"(parent node),这个例子能说明 托马斯·杰斐逊 是 阿龙·伯尔 的父亲吗?

我让你们的同人文来决定,没有任何"子节点"的节点,也就是"树"结束的地方,叫"叶节点"(leaf),在这里的例子中,节点最多只可以有 2 个子节点,因此叫二叉树(binary tree)。

但你可以随便改,弄成 3个,4个,或更多,甚至节点可以用链表存所有子节点,"树"的一个重要性质是(不管现实中还是数据结构中),"根"到"叶"是单向的,如果根连到叶,叶连到根就很奇怪。

如果数据随意连接,包括循环,可以用"图"表示,还记得上集用路连接城市的"图"吗?这种结构可以用有多个指针的节点表示,因此没有根、叶、子节点、父节点这些概念,可以随意指向!

以上概述了计算机科学中,最主要的一些数据结构,这些基本结构之上,程序员做了各种新变体,有不同性质。比如"红黑树"和"堆",不同数据结构适用于不同场景,选择正确数据结构会让工作更简单,所以花时间考虑用什么数据结构是值得的。

幸运的是,大多数编程语言自带了预先做好的数据结构,比如,C++有"标准模板库",Java有"Java 类库",程序员不用浪费时间从零写,时间可以花在更有趣的事情。

又提升了一层抽象!

下节课见。


以上内容就是 14. 数据结构 的内容,感兴趣的同学记得点赞、关注、转发、收藏哦!

我会不定期发布课程的讲解!

更多技术文章,公众号 “摸鱼IT” 锁定 -上午11点 - ,感谢大家关注、转发、点赞!

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

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

相关文章

回首2023: 程序员跳出舒适圈

1 前言 今天的冬日暖阳高照,照耀着我穿着羽绒服的身体,让我感到火一般的燥热,仿佛错觉中已经到了阳春三月。刚刚把孩子洗好,我坐在电脑前,准备整理一下思绪,回顾一下2023年的生活和工作。 2 2023 回顾 回…

Java毕业设计—springboot健身房管理系统

一、项目背景介绍: 随着人们生活水平的提高和健康意识的增强,健身行业逐渐兴起并迅速发展。而现代化的健身房管理系统已经成为健身房发展的必备工具之一。传统的健身房管理方式已经无法满足现代化健身房的需求,需要一种更加高效、智能、安全…

CentOS虚拟机硬盘管理

CentOS虚拟机硬盘管理 一、创建虚拟机时分配硬盘 创建虚拟机时,在下图这个页面需要重新选择一下硬盘,可以对硬盘进行配置。 默认自动分区 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e9ce72af3d934e75be95f7f86860e92b.png 选择确认分…

类的加载顺序问题-demo展示

面试的的时候经常会被问到包含静态代码块、实例代码块和构造器等代码结构的加载顺序问题,下面借用一个面试题,回顾一下类的代码加载顺序。 public class AooTest {public static void main(String[] args) {AooTest.f1();}static AooTest test1 new Ao…

免费的云服务器推荐~三丰云

对于许多初创企业和小型公司来说,寻找一个经济实惠且可靠的云服务提供商是至关重要的。在这方面,三丰云以其免费虚拟主机和云服务器吸引了大量用户。 1. 注册与界面 注册三丰云的账户过程简单明了,只需按照步骤填写必要信息即可。其界面设计…

Centos7:Jenkins+gitlab+node项目启动(1)

Centos7:Jenkinsgitlabnode项目启动(1) Centos7:Jenkinsgitlabnode项目启动(1)-CSDN博客 Centos7:Jenkinsgitlabnode项目启动(2) Centos7:Jenkinsgitlabnode项目启动(2)-CSDN博客 Centos7:Jenkinsgitlabnode项目启…

逻辑卷使用和扩容

1.逻辑卷管理LVM ( Logical Volume Manager) 是 Linux 下对硬盘分区的一种管理机制 /boot分区用于存放引导文件,不能基于lvm创建 2.分区缺点: 无法动态扩容 必须使用连续的空间 没有备份 逻辑卷 lvm: 可以动态扩容…

Python高级用法:生成器(generator)

生成器(generator) 生成器是一种返回生成序列的方法,与直接使用列表等方式返回序列的方式不同的是,他的生成可以是无限的。 生成器可以与next搭配使用,可以被看作是一种特殊的迭代器。 yield语句 yield一般与循环相…

单集群400TB,OceanBase稳定支撑快手核心业务场景

一款日均超过千万人访问的短视频 App 快手,面对高并发流量如何及时有效地处理用户请求?通过在后端配置多套 MySQL 集群来支撑高流量访问,以解决大数据量存储和性能问题,这种传统的 MySQL 分库分表方案有何问题?快手对分…

【C++】STL 容器 - set 集合容器 ① ( set 集合容器简介 | set 集合容器操作的时间复杂度 | set 集合容器常用操作 )

文章目录 一、set 集合容器1、set 集合容器简介2、set 集合容器操作的时间复杂度3、set 集合容器常用操作 二、代码示例 - set 集合容器1、代码示例2、执行结果 一、set 集合容器 1、set 集合容器简介 C 语言中的 STL 容器中的 set 容器 , 是 " 集合容器 " , 容器中…

在Go语言中处理HTTP文件上传

大家好,我是你们可爱又迷人的编程小助手,今天要带你们一起探讨在Go语言中如何处理HTTP文件上传,让我们把这场技术之旅变得轻松有趣吧! 首先,想象一下这个场景:你是一个网站的开发者,用户们急切…

使用 SSH 方式实现 Git 远程连接GitHub

git是目前世界上最先进的分布式版本控制系统,相比于SVN,分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作!当有网络的时候,再把本地提交推送一下就完成了同步&…

MongoDB Certified Associate Developer 认证考试心得

介绍 前段时间通过了 MongoDB Associate Developer 考试,也记下了一些心得,结果忘记发出来了,现在重新整理下。通过考试后证书是这样的: MongoDB 目前有两个认证证书 1. MongoDB Associate Developer 认证掌握使用MongoDB 来构建现代应用…

【一分钟】ThinkPHP v6.0 (poc-yaml-thinkphp-v6-file-write)环境复现及poc解析

写在前面 一分钟表示是非常短的文章,只会做简单的描述。旨在用较短的时间获取有用的信息 环境下载 官方环境下载器:https://getcomposer.org/Composer-Setup.exe 下载文档时可以设置代理,不然下载不上,你懂的 下载成功 cmd cd…

Linux环境grep搜索方法记录

1 grep grep 命令,用来搜索字符串所在位置,可以具体到不同文件,不同行; 在Linux 下,查看命令释义如下 zhaocubuntu2004:~$ grep --help Usage: grep [OPTION]... PATTERNS [FILE]... Search for PATTERNS in each FI…

C#获取windows系统资源使用情况

1.前言 之前有一篇博客介绍如何获取Linux服务器上的资源使用情况《Java 获取服务器资源(内存、负载、磁盘容量)》,这里介绍如何通过C#获取Window系统的资源使用。 2.获取服务器资源 2.1.内存 [DllImport("kernel32.dll")][retu…

Maven项目提示Ignored pom.xml问题

1 环境 (1)IDEA开发工具:2022.2.1 (2)JDK:Java17(Spring6要求JDK最低版本是Java17) (3)Spring:6.1.2 (4)Maven 3.8.8 2 …

C#上位机与欧姆龙PLC的通信06---- HostLink协议(FINS版)

1、介绍 对于上位机开发来说,欧姆龙PLC支持的主要的协议有Hostlink协议,FinsTcp/Udp协议,EtherNetIP协议,本项目使用Hostlink协议。 Hostlink协议是欧姆龙PLC与上位机链接的公开协议。上位机通过发送Hostlink命令,可…

计算机组成原理复习7

内存管理 文章目录 内存管理存储器概述存储器的分类按在计算机中的作用(层次)分类按存储介质分类按存取方式分类按信息的可保存性分类 存储器的性能指标存储容量单位成本存储速度:数据传输率数据的宽度/存储周期 存储器的层次化结构多级存储系…

Java注解学习,一文掌握@Autowired 和 @Resource 注解区别

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…