遞歸雖直觀但受限於 PHP 預設 256 層遞歸深度。迭代版使用 while 迴圈配合 array_unshift 同樣能高效構建祖先路徑,且無深度限制。
$area = [
['id'=>1, 'area'=>'北京', 'pid'=>0],
['id'=>2, 'area'=>'廣西', 'pid'=>0],
['id'=>3, 'area'=>'廣東', 'pid'=>0],
['id'=>4, 'area'=>'福建', 'pid'=>0],
['id'=>11, 'area'=>'朝陽區', 'pid'=>1],
['id'=>12, 'area'=>'海澱區', 'pid'=>1],
['id'=>21, 'area'=>'南寧市', 'pid'=>2],
['id'=>45, 'area'=>'福州市', 'pid'=>4],
['id'=>113, 'area'=>'亞運村', 'pid'=>11],
['id'=>115, 'area'=>'奧運村', 'pid'=>11],
['id'=>234, 'area'=>'武鳴縣', 'pid'=>21],
];
<?php
function familyTreeIterative($arr, $id) {
$list = [];
while ($id) {
$found = false;
foreach ($arr as $v) {
if ($v['id'] == $id) {
array_unshift($list, $v['area']); // 头插法,保證根在前
$id = $v['pid'];
$found = true;
break;
}
}
if (!$found) break; // 找不到父節點,防止死循環
}
return $list;
}
$result = familyTreeIterative($area, 113);
print_r($result);
Array
(
[0] => 北京
[1] => 朝陽區
[2] => 亞運村
)
pid=0 (根節點) 時循環結束。$found 標記處理資料髒污 (如 pid 指向不存在節點、循環引用)。[$id => $node] 映射,將 O(n) 查找降為 O(1)。| 維度 | 遞歸 | 迭代 |
|---|---|---|
| 代碼可讀性 | 高 (符合樹遞歸定義) | 中 |
| 深度限制 | 受限 (預設 256) | 無限制 |
| 記憶體佔用 | 調用棧累積 | 常數級 |
| 適用場景 | 淺層樹、快速原型 | 深層樹、高頻調用、長期運行服務 |