首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 非遞歸實現無限分類(樹狀陣列)兩大核心函式

     編輯:PHP 綜合知識

傳統遞歸建樹在資料量大時易爆堆疊、效能低。本文提供兩個純迴圈函式,一次遍歷即可將鄰接列表(id, pid)轉換為父節點樹與子節點樹,記憶體佔用極低、速度極快。

核心函式:find_parent(建立父節點索引樹)

/**
 * 建立父節點樹狀陣列
 * @param array  $ar  鄰接列表資料
 * @param string $id  主鍵欄位名(預設 'id')
 * @param string $pid 父鍵欄位名(預設 'pid')
 * @return array 以 id 為鍵的多維陣列,含 parent 子陣列
 */
function find_parent($ar, $id='id', $pid='pid') {
    // 1. 建立 id => row 索引
    foreach ($ar as $v) $t[$v[$id]] = $v;
    // 2. 遍歷掛載 parent 參考
    foreach ($t as $k => $item) {
        if ($item[$pid]) {
            if (!isset($t[$item[$pid]]['parent'][$item[$pid]])) {
                $t[$k]['parent'][$item[$pid]] = &$t[$item[$pid]];
            }
        }
    }
    return $t;
}

核心函式:find_child(建立子節點樹)

/**
 * 建立子節點樹狀陣列
 * @param array  $ar  鄰接列表資料
 * @param string $id  主鍵欄位名
 * @param string $pid 父鍵欄位名
 * @return array 以 id 為鍵的多維陣列,含 child 子陣列
 */
function find_child($ar, $id='id', $pid='pid') {
    foreach ($ar as $v) $t[$v[$id]] = $v;
    foreach ($t as $k => $item) {
        if ($item[$pid]) {
            $t[$item[$pid]]['child'][$item[$id]] = &$t[$k];
        }
    }
    return $t;
}

使用範例

$data = [
    ['ID'=>1, 'PARENT'=>0, 'NAME'=>'祖父'],
    ['ID'=>2, 'PARENT'=>1, 'NAME'=>'父親'],
    ['ID'=>3, 'PARENT'=>1, 'NAME'=>'叔伯'],
    ['ID'=>4, 'PARENT'=>2, 'NAME'=>'自己'],
    ['ID'=>5, 'PARENT'=>4, 'NAME'=>'兒子'],
];

$p = find_parent($data, 'ID', 'PARENT');
$c = find_child($data, 'ID', 'PARENT');

// 輸出 $c[1] 即為以「祖父」為根的完整子樹
print_r($c[1]);

輸出結構說明(以 $c 為例)

Array
(
    [1] => Array
        (
            [ID] => 1
            [PARENT] => 0
            [NAME] => 祖父
            [child] => Array
                (
                    [2] => Array
                        (
                            [ID] => 2
                            [PARENT] => 1
                            [NAME] => 父親
                            [child] => Array
                                (
                                    [4] => Array
                                        (
                                            [ID] => 4
                                            [PARENT] => 2
                                            [NAME] => 自己
                                            [child] => Array
                                                (
                                                    [5] => Array
                                                        (
                                                            [ID] => 5
                                                            [PARENT] => 4
                                                            [NAME] => 兒子
                                                        )
                                                )
                                        )
                                )
                        )
                    [3] => Array
                        (
                            [ID] => 3
                            [PARENT] => 1
                            [NAME] => 叔伯
                        )
                )
        )
    // ... 其餘節點同樣包含 child 結構
)

優勢分析

指標傳統遞歸本文非遞歸
時間複雜度O(n²) 多次遍歷O(n) 單次遍歷
堆疊風險深層級易堆疊溢位無遞歸,零風險
記憶體函式呼叫堆疊佔用僅一層陣列參考
程式碼量約 15 行各 10 行

應用場景

  • 後台選單/分類無限級樹狀顯示
  • 組織架構圖(員工-主管關係)
  • 評論回覆巢狀結構
  • 商品分類麵包屑導航

進階:直接輸出 HTML 選單

function render_menu($tree, $rootId=0) {
    if (!isset($tree[$rootId]['child'])) return '';
    $html = '
    '; foreach ($tree[$rootId]['child'] as $node) { $html .= '
  • ' . htmlspecialchars($node['NAME']); $html .= render_menu($tree, $node['ID']); $html .= '
  • '; } $html .= '
'; return $html; } echo render_menu($c); // 直接輸出完整巢狀
  • 選單

無遞歸建樹 + 遞歸渲染(僅輸出層),兼顧建構效能與輸出便利性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved