上文说过,物理构造是用于确定数据以何种办法存储的。其他的数据构造(树、图)、算法等基本都是建立在这样一个物理构造之上的,也可以说,物理构培养是数据构造的根本。在这里,我们先先容两个物理构造,也是我们将来学习数据构造的基石,它们便是顺序表和链表。
顺序表不扯繁芜的定义,不扯什么数学表达式,我们最直不雅观的理解,顺序表便是数组。
是不是非常大略,没错,在 PHP 或者 C 的天下中,我们就把顺序表定义为数组,而相同的名词还包括:顺序存储、顺序构造等。只要看到这种名词,立时想到数组就可以了。当然,在 Java 中,我们也可以将 List 这类的凑集当成是顺序存储构造。不过须要把稳的是,Java 的 HashMap ,在 PHP 中因此键值对形式定义的数组,它们是哈希表(Hash),从形式上来说,他们并不是顺序的。在这里我们一定要记住,像数组下标递增这样顺序构造的才是顺序存储构造。

顺序表一样平常占用连续的内存空间。不仅逻辑上,连物理空间上都是相邻连续的。
链表链表一样平常在 C 中会定义为一个构造体,个中包括数据和指向下一个链表的指针,它不是顺序的,虽然逻辑是有顺序的(按指针指向),但在物理是可以分开的。也便是说,链表不用占用连续的内存空间,不须要在初始化的时候像数组一样给定长度。
在 PHP 中,我们没有构造体这种语法形式,以是我们直策应用类来表示链表构造。
class Node{ public $data; public Node $next;}
这便是一个大略的链表构造,我们可以把它叫做一个“结点”。data 中存放我们要保存的数据,可以是任意类型。而 next 则是我们下一个链表结点。如果我们须要大略的遍历链表,直接一直的调用 next 直到它为空即可。
while($n->next){ $n = $n->next; echo $n->data, PHP_EOL;}
上图便是关于链表的逻辑状态以及它的遍历方向。详细的链表操作干系函数我们将在后面的文章中进行讲解。
链表有很多种形式,上面我们定义的是一个大略的单向链表。我们还可以定义双向链表(加一个 prev 指向上一个结点),循环链表(末了一个next指回第一个结点)以及双向循环链表(末了一个next指回第一个结点,第一个的 prev 指向末了一个结点)。关于这些内容,我们也会放到后面的文章中逐一讲解。
线性表理解了顺序表和链表之后,我们末了就来说说线性表。
实在,顺序表和链表这两种物理构造在默认状态下所实现的便是“顺序表”这个逻辑数据构造。
顺序表:由n(n>0)个数据特性相同的元素构成的有限序列(严蔚敏版)
把稳几个关键点:
有限:数组长度、链表内存大小
序列:逻辑有序(数组是逻辑和物理都有序,链表是逻辑有序而物理无序)
数据特性相同:PHP 中不明显,C 或 Java 中数组是固定类型的,而且也要给一个初始长度
为什么说线性表这么主要呢?我们想想 MySQL 这样一行一行存储数据的关系型数据库,一张数据表不便是一个线性表吗?特殊是我们做 PHP 的程序员,每天都是在和数组(数据库读出来的数据一样平常都放到数据中)打交道(当然,我们用哈希可能更多些),也便是说,我们在做开拓的时候,每天都在打仗这个东西,你说它主要不主要。
而 树 和 图 这些数据构造却并不是线性表,在现实的归类中,它们是属于 非线性表 的范畴的。线性表在个很大的特点是只有前后关系,不管是链表还是数组,它们都是遵照着这种前后关系的,但是在 树 和 图 中,除了前后之外,还有高下旁边等更繁芜的关系。虽说它们的基本表现形式依然是利用数组和链表,但是从严格的角度来说,或者从考试口试的角度来说,它们真的不属于线性构造,而该当划分到 非线性构造 中。
总结本日这篇文章是学习数据构造中根本的根本。当然,有条件的最好还是看看 C 用构造体是如何定义数组、链表的,PHP 在底层已经帮我们办理了太多问题,以是这些原始的语法构造我们已经用不到了。能够用 C 来学习数据构造是更加推举的形式。
下一篇文章我们将先容的是顺序表(数组)的线性表干系逻辑操作。
参考资料:
《数据构造》第二版,严蔚敏
《数据构造》第二版,陈越
《数据构造高分条记》2020版,天勤考研