使用多维数组表示数据结构

在接下来的章节中,我们将讨论许多不同的数据结构和算法。图是我们将重点讨论的数据结构之一。我们已经知道图数据结构的定义。大多数情况下,我们会使用 PHP 多维数组将数据表示为邻接矩阵。让我们来看看下面的图:

image 2023 11 07 11 02 55 199

现在,如果我们将图的每个节点视为数组的值,则可以将节点表示为:

$nodes = ['A', 'B', 'C', 'D', 'E'];

但这只会给我们节点名称。我们无法在节点之间连接或创建关系。为此,我们需要构造一个二维数组,其中节点名称为键,值根据两个节点的互连性为 0 或 1。由于图中没有提供方向,我们不知道 A 是否连接到 C 或者是否连接到 A。因此我们假设两者相互连接。

首先,我们需要为图创建一个数组,并将二维数组的每个节点初始化为 0。以下代码将准确地执行此操作:

$graph = [];
$nodes = ['A', 'B', 'C', 'D', 'E'];
foreach ($nodes as $xNode) {
    foreach ($nodes as $yNode) {
        $graph[$xNode][$yNode] = 0;
    }
}

让我们使用下面的代码打印数组,以便在定义节点之间的连接之前看到数组的实际外观:

foreach ($nodes as $xNode) {
    foreach ($nodes as $yNode) {
        echo $graph[$xNode][$yNode] . "\t";
    }
    echo "\n";
}

由于没有定义节点之间的连接,所有单元格都显示为 0,因此输出结果如下:

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

现在,我们将定义节点的连接性,两个节点之间的连接将表示为 1,就像下面的代码一样:

$graph["A"]["B"] = 1;
$graph["B"]["A"] = 1;
$graph["A"]["C"] = 1;
$graph["C"]["A"] = 1;
$graph["A"]["E"] = 1;
$graph["E"]["A"] = 1;
$graph["B"]["E"] = 1;
$graph["E"]["B"] = 1;
$graph["B"]["D"] = 1;
$graph["D"]["B"] = 1;

由于图中没有给出方向,我们将其视为不定向图,因此我们将每个连接的两个值都设为 1。对于 A 和 B 之间的连接,我们将 $graph["A"]["B"]$graph["B"]["A"] 都设为 1。我们将在后面的章节中学习更多关于定义节点间连接性的知识,以及为什么要这样做。现在我们只关注如何将多维数组用于数据结构。我们可以重新打印矩阵,这次的输出结果如下:

0 1 1 0 1
1 0 0 1 1
1 0 0 0 0
0 1 0 0 0
1 1 0 0 0

在第 9 章 "将图形付诸实践" 中了解更多有关图形及其运算的知识,会更加有趣和好玩。

使用 SplFixedArray 方法创建固定大小的数组

到目前为止,我们已经探索了 PHP 数组,我们知道,我们并没有定义数组的大小。PHP 数组可以根据我们的需求增大或缩小。这种灵活性给内存使用带来了极大的不便。我们将在本节中探讨这个问题。现在,让我们把重点放在使用 SPL 库创建固定大小的数组上。

我们为什么需要固定大小的数组?它有什么额外优势吗?答案是,当我们知道数组中只需要一定数量的元素时,就可以使用固定大小的数组来减少内存使用。在分析内存使用情况之前,让我们举几个使用 SplFixedArray 方法的例子:

$array = new SplFixedArray(10);

for ($i = 0; $i < 10; $i++)
    $array[$i] = $i;

for ($i = 0; $i < 10; $i++)
    echo $array[$i] . "\n";

首先,我们创建一个新的 SplFixedArray 对象,并定义其大小为 10。剩下的几行实际上遵循了我们在普通 PHP 数组赋值和检索中使用的相同原则。如果我们要访问的索引超出范围(这里是 10),就会出现异常:

PHP Fatal error: Uncaught RuntimeException: Index invalid or out of range

PHP 数组和 SplFixedArray 之间的基本区别是:

  • SplFixedArray 必须有固定定义的大小

  • SplFixedArray 的索引必须是整数,范围在 0 到 n 之间,其中 n 是我们定义的数组大小

当我们有很多已知大小的已定义数组,或者有数组最大所需大小的上限时,SplFixedArray 方法会非常方便。但如果我们不知道数组的大小,那么最好使用 PHP 数组。