php生成樹狀層級子孫樹-迭代篇

關於簡單的方式獲取樹狀層級子孫樹的方案我已經寫過了,在這裏,當時是用簡單的遞歸實現的,但是現在回頭想想,如果層級很多,數據也很多,用遞歸感覺還是會不穩妥,這就有必要想辦法轉換爲迭代來實現了。

以下是迭代的代碼實現

<?php
$data = [
    ['id' => 1, 'name' => '中國', 'pid' => 0],
    ['id' => 2, 'name' => '江蘇', 'pid' => 1],
    ['id' => 6, 'name' => '工業園區', 'pid' => 5],
    ['id' => 7, 'name' => '中新大道', 'pid' => 6],
    ['id' => 9, 'name' => '鄞州區', 'pid' => 4],
    ['id' => 3, 'name' => '浙江', 'pid' => 1],
    ['id' => 10, 'name' => '天童南路', 'pid' => 8],
    ['id' => 8, 'name' => '首南街道', 'pid' => 9],
    ['id' => 4, 'name' => '寧波', 'pid' => 3],
    ['id' => 5, 'name' => '蘇州', 'pid' => 2],
    ['id' => 11, 'name' => '北京', 'pid' => 1],
    ['id' => 12, 'name' => '海淀', 'pid' => 11],
];

function getTree($data = [], $parent = 0)
{
    $target_list = [$parent];
    $tree = [];
    $level = 0;
    while (!empty($target_list)) {
        $flag = false;
        foreach ($data as $key => $value) {
            if ($value['pid'] == $parent) {
                $level++;
                $value['level'] = $level;
                $tree[] = $value;
                $target_list[] = $parent = $value['id'];
                unset($data[$key]);
                $flag = true;
            }
        }
        if (!$flag) {
            $level--;
            array_pop($target_list);
            $parent = end($target_list);
        }
    }
    return $tree;
}

$list = getTree($data, 0);

foreach ($list as $v) {
    $level = isset($v['level']) ? $v['level'] : 0;
    echo str_repeat('    ', $level - 1) . $v['name'] . "\r\n";
}

輸出結果如下:

這裏我特意把傳遞的數據打亂順序,看看它能不能獲取到正確的順序層級,這樣一看也沒問題。

這個迭代的核心思想是用target_list去存儲當前要找的那個父級,找到了就追加進去,層級++,找不到就彈出來一個,層級--

可以看一下以前我寫遞歸的方式,遞歸就很好理解,但是自己心裏面就是感覺效率上和安全上面差點意思,代碼如下:

用數據庫的數據算了一下效率,其實差不多,沒有很明顯的差距,當數據量只有幾條的時候迭代比遞歸甚至還慢一點,當數據量有四千多條的時候(省市縣三級數據)迭代比遞歸稍微快一點點,但是真的不明顯。

看來這裏還需要一個更強更好的算法來解決該問題啊!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章