【PHP数据结构】在学数据结构和算法的时候我们究竟学的是啥?
一说到数据结构与算法,大家都会避之不及。这本来是一门专业基础课,但是大部分人都并没有学好,更不用说我这种半路出家的码农了。说实话,还是很羡慕科班出身的程序员,因为你们在日常工作或者面试中,只需要复习一下就好了,而我则是完全的从头开始学。不过,还好一切都不晚,在这里,我们就用 PHP 作为示例代码,来和大家一起真正的从头学一遍恐怖的数据结构与算法。
数据结构
什么是数据结构呢?
数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系
这是严蔚敏老师在《数据结构》第二版中对数据结构的定义。其实,就是关于数据的一种组合形式。就像你去一家书店,或者是图书馆,或者是你家的书柜。这些书应该怎么摆放呢?关于书的摆放形式,就是数据结构。你可以乱七八糟的摆放,也可以分门别类的摆放,也可以根据自己的兴趣爱好摆放,也可以将最常用的书放在手边,将不常看的书放在柜子的深处。这些都是数据结构。
在程序世界中,数据结构包含两种形式,一种是逻辑结构,一种是物理结构。
逻辑结构
即使你完全没有接触过数据结构,但只要你学习过编程,一定会多多少少地听说过这样一些名词:集合、线性表、树、图,它们指的就是数据结构中的逻辑结构。也就是从逻辑关系上描述数据,是具体问题抽象出来的数学模型。比如我们将书进行分类,每个分类下放着相对应的书籍,这就是一种树形结构。或者我们将书按书名拼音建立索引,然后在书架上贴上索引标签,这就是一种哈希结构。
逻辑结构将是我们整个学习中的一个重点,因为各种算法都是针对这些结构的操作实现。这个我们在下面的算法解释中再进行详细的说明。
物理结构
物理结构主要是数据的物理存储方式,也叫做存储结构。这个非常好记,它只有两种形式,顺序存储结构和链式存储结构。通常,顺序存储结构我们使用数组来表示,而链式存储结构在 C语言 中使用结构体的指针来表示,但在 PHP 中,链式结构我们将使用类来表述。
上面说的那些逻辑结构,都可以用顺序或者链式的方式来实现,不管使用哪种方式,都可以完成对应逻辑结构的算法操作,但不同的形式或者算法又有不同的效率。而效率,正是整个数据结构和算法学习核心中的核心。
算法
接下来我们看看什么是算法。
算法是一个有限指令集,它接受一些输入(有些情况下不需要输入),产生输出,并一定在有限步骤之后终止
这是陈越老师在浙大版《数据结构》第二版中对于算法的定义。其实我们简单点理解的话,针对上面的数据结构的一系列操作,就是算法。比如说我们定义了一个树,如何遍历这颗树呢?这就是一个算法,遍历一颗树有先序、中序、后序,也可以进行层序遍历,有这么多种方法,哪种好?哪种不好?用哪种物理结构?线性还是链式?这些结论都以算法的执行效率为基础。可以说,算法种类繁多,效率也千差万别,但是,不能一棒子打死说某个算法一定不好,每种算法也有它不同的应用场景。这就是我们要研究算法的原因。
关于算法,我们最关心的是它的效率,这个效率在这里我们使用的是时间复杂度和空间复杂度来定义的。
时间复杂度
时间复杂度一般使用 O(n) 来表示,它关心的是问题规模和语句频度,一般会以 n 表示问题规模 (注意,这个 n 是未知的,如果这个 n 是已知的,那么它就是常数阶)。这个 n 有可能是一个常数(n 明确等于多少),记成 O(1) 。这是最好的情况,也可以线性增长,如 O(n) 。当然也可能对数或指数级增长,O(logN) 、 O(N^2),当然最要不得的是 O(2^N) 级的增长,这种情况下可能有生之年你都看不到运算的结果了。
我们可以看看简单的一段代码来分析它的时间复杂度:
echo $a++, PHP_EOL; // O(1)
$n = 10; // 假设一个数量用于测试,实际这个 n 是未知的,如果面试题代码中真的出现了这种已知 n 的情况,那么这个算法就是 O(1)
for($i = 0;$i<$n;$i++){
echo $i, PHP_EOL;
}
// O(n)
for($i = 0;$i<$n;$i*=2){
echo $i, PHP_EOL;
}
// O(logN)
for($i = 0;$i<$n;$i++){
for($j = 0;$j<$n;$j++){
echo $i, $j, PHP_EOL;
}
}
// O(N^2)
从上面代码中可以看出,循环嵌套次数与 n 的增长有很大的关系,另外就是看在循环内部的操作也会影响到增长的情况。比如如果我们是这样一段代码:
$n = 10; // 假设一个数量,实际这个 n 是未知的
$m = 3; // 假设一个数量,实际这个 m 是未知的
for($i = 0;$i<$n;$i++){
for($j = 0;$j<$m;$j++){
echo $i, $j, PHP_EOL;
}
}
那么它的时间复杂度就不是 O(N^2) 而是,O(NM) ,因为我们这两层循环并不是都是对最大的 N 的操作,而是 N * M 的操作。但是,如果当 M 很大甚至等于 N 的时候,那么这个算法也就成为了 N^2 。
对于时间复杂度的分析其实是需要一些数学功底的,但是对于我这种半吊子出身的码农来说,把握住循环层次以及循环内的操作情况就可以大致地分析出一段算法的时间复杂度了。当然,对于某些大厂比较刁钻的面试题来说,还是需要用数学方法进行分解求得正确的时间复杂度。
另外,在一段算法或者说一个函数中,时间复杂度以最大的那个为准,同时,也要考虑最好和最差时间复杂度,因为基于数据规模有可能在数据量大的时候时间复杂度会越来越惨。这个时候我们就会以最差时间复杂度来作为这一段算法的最终时间复杂度。
关于时间复杂度的问题,可以参考各类算法书籍,当然最好是以大学教材及练习题为主,多做题就能掌握得更深入。
空间复杂度
相对时间复杂度来,空间复杂度在数据结构和算法中要关心的少一些,因为大部分情况下我们只借助一个第三方变量的话,这个空间复杂度就是 O(1) 。而如果需要借助一个数组或者链表来实现算法的话,这个算法的空间复杂度就是 O(n) 。
一般情况下我们不太会去过于的关注空间复杂度,因为大部分算法基本都会维持在 O(1) 或 O(n) 这个级别。当然,也就一些算法会出现占用非常大的空间复杂度的情况,这样分分钟就能撑爆你的内存。当在遇到这类算法的时候,我们会单独来说明空间复杂度的情况。
总结
第一篇文章都是以理论方面的东西为基础的,这也是学习数据结构与算法的实际情况,必须是理论与实际相结合的学习。让我们从此开始,迈向这个深不见底的超级大坑吧!!
参考资料:
《数据结构》第二版,严蔚敏
《数据结构》第二版,陈越
《数据结构高分笔记》2020版,天勤考研
===============
关注公众号:【硬核项目经理】获取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料
知乎、公众号、抖音、头条搜索【硬核项目经理】
B站ID:482780532
【PHP数据结构】在学数据结构和算法的时候我们究竟学的是啥?的更多相关文章
- 前端要不要学数据结构&算法
我们都知道前端开发工程师更多偏向 DOM 渲染和 DOM 交互操作,随之 Node 的推广前端工程师也可以完成服务端开发.对于服务端开发而言大家都觉得数据结构和算法是基础,非学不可.所以正在进行 No ...
- 数据结构C语言版 弗洛伊德算法实现
/* 数据结构C语言版 弗洛伊德算法 P191 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h>#include <limits.h> # ...
- 简学Python第二章__巧学数据结构文件操作
#cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...
- hdu 3336:Count the string(数据结构,串,KMP算法)
Count the string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 每周一道数据结构(四)A*算法&博弈树α-β剪枝
A*算法/博弈树 前阵子考试学了A*算法.博弈树和回溯,自己真是愚蠢至极,根本没就搞明白这些,所以对于这些算法问道的话就不能说清楚,也记不住,所以才有了这篇笔记.在这里感谢面试我的那位工程师~~ A* ...
- 你真的懂redis的数据结构了吗?redis内部数据结构和外部数据结构揭秘
Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet. 很多人面试时都遇到过这种场景吧? 其实除了上面的几种常见数据结构,还需要加上数据结 ...
- 一步步教你轻松学支持向量机SVM算法之案例篇2
一步步教你轻松学支持向量机SVM算法之案例篇2 (白宁超 2018年10月22日10:09:07) 摘要:支持向量机即SVM(Support Vector Machine) ,是一种监督学习算法,属于 ...
- 一步步教你轻松学支持向量机SVM算法之理论篇1
一步步教你轻松学支持向量机SVM算法之理论篇1 (白宁超 2018年10月22日10:03:35) 摘要:支持向量机即SVM(Support Vector Machine) ,是一种监督学习算法,属于 ...
- 一步步教你轻松学关联规则Apriori算法
一步步教你轻松学关联规则Apriori算法 (白宁超 2018年10月22日09:51:05) 摘要:先验算法(Apriori Algorithm)是关联规则学习的经典算法之一,常常应用在商业等诸多领 ...
随机推荐
- Ubuntu Server安装telnet服务时"Unable to locate package telnetd"解决方法
装好Ubuntu Server 12.04后,用apt-get安装telnetd报"E: Unable to locate package telnetd",解决方法如下: 虚拟机 ...
- Spring学习01(IOC)
1.Spring概述 简介 2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架. 2004年3月24日,Spring框架以interface21框架为基础,经过 ...
- Shell-02-数据类型
shell数据类型 shell常用的数据类型有 字符串.整数型.数组 字符串 字符串是shell编程中最常用最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号 建议使用双引号,因为双 ...
- DVWA-全等级文件上传
DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...
- cpu设计实践1
本栏目将实现一个简单cpu(8-32位)的设计,使用xinlink spatan6平台
- NOIP 模拟 $23\; \rm 赛$
题解 将所有物品分成四类,分别为两人共同喜欢的,只有一人喜欢的,没人喜欢的. 首先,先从两人共同喜欢的物品里找出 \(k\) 个,这时,就要从剩余的找出 \(\rm m-k\) 个,而且是最小的. 用 ...
- 【设计模式】装饰者模式(DecoratorMode0
From: https://liudongdong1.github.io/ 装饰者模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,增加对象功能来说,装饰模式比生成子类实 ...
- Qt元对象和属性系统详解
Qt 是一个用标准 C++ 编写的跨平台开发类库,它对标准 C++ 进行了扩展,引入了元对象系统.信号与槽.属性等特性,使应用程序的开发变得更高效. 本节将介绍 Qt 的这些核心特点,对于理解和编写高 ...
- spring学习日志四
一.spring对JDBC的支持 JdbcTemplate 简介 为了使 JDBC 更加易于使用, Spring 在 JDBC API 上定义了一个抽象层, 以此建立一个 JDBC 存取框架. 作为 ...
- Object 的wait()方法
The java.lang.Object.wait() causes current thread to wait until another thread invokes the notify() ...