You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP Category类的递归与无递归树遍历打印实现求助

非递归方式打印PHP Category类的实现方案

嘿,我来帮你搞定这个非递归的分类打印需求!先确认下你的Category类定义是这样的(我帮你补全了格式):

class Category { 
    public $name; 
    public $id; 
    public $subCats = array(); 

    public function __construct($name = "", $id = "") { 
        $this->name = $name; 
        $this->id = $id; 
    } 

    public function add_sub_cat($subCat) { 
        array_push($this->subCats, $subCat); 
    } 
}

你提到已经实现了递归打印,那我们直接来看迭代(基于栈)的实现方案——递归本质是利用PHP的调用栈,我们可以手动用栈结构来模拟这个过程,避免递归深度过大导致的栈溢出问题。

迭代打印函数实现

这里我们用栈来保存每个待处理的分类节点,同时记录当前节点的层级(用来控制缩进,让输出结构更清晰):

function iterative_print($rootCategory) {
    // 初始化栈,每个元素是包含分类对象和层级的数组
    $stack = array();
    // 根节点层级设为0
    array_push($stack, array('category' => $rootCategory, 'level' => 0));

    echo "<ul>";
    while (!empty($stack)) {
        // 弹出栈顶元素
        $current = array_pop($stack);
        $category = $current['category'];
        $level = $current['level'];

        // 生成缩进,层级越深缩进越多
        $indent = str_repeat('&nbsp;&nbsp;', $level);
        // 打印当前分类
        echo "<li>{$indent}<div id='category-name'><p>{$category->name} (ID: {$category->id})</p></div>";

        // 如果有子分类,需要逆序压入栈(因为栈是后进先出,逆序后弹出顺序才和递归一致)
        if (!empty($category->subCats)) {
            echo "<ul>";
            // 逆序遍历子分类
            for ($i = count($category->subCats) - 1; $i >= 0; $i--) {
                array_push($stack, array(
                    'category' => $category->subCats[$i],
                    'level' => $level + 1
                ));
            }
            echo "</ul>";
        }
        echo "</li>";
    }
    echo "</ul>";
}

代码逻辑解释

  1. 栈初始化:把根分类节点和初始层级(0)压入栈中。
  2. 循环处理栈元素:只要栈不为空,就弹出栈顶元素:
    • 打印当前分类,用层级控制缩进,让嵌套结构更直观。
    • 如果当前分类有子分类,逆序压入栈:因为栈是“后进先出”的结构,逆序压入后,弹出时会按照原顺序处理子分类,和递归的遍历顺序保持一致。
  3. HTML结构保持:和递归实现一样,用<ul>和<li>构建嵌套的列表结构,保证输出的HTML语义化。

测试示例

我们来创建一个分类结构测试下:

// 创建分类实例
$root = new Category('电子产品', '1');
$phone = new Category('手机', '1-1');
$laptop = new Category('笔记本电脑', '1-2');
$iphone = new Category('iPhone系列', '1-1-1');
$android = new Category('安卓手机', '1-1-2');

// 添加子分类
$root->add_sub_cat($phone);
$root->add_sub_cat($laptop);
$phone->add_sub_cat($iphone);
$phone->add_sub_cat($android);

// 调用迭代打印函数
iterative_print($root);

输出的HTML结构会是嵌套的列表,和递归实现的效果完全一致,但不会有递归深度限制的问题。

为什么用栈而不是队列?

如果用队列的话,会变成广度优先遍历(BFS),而递归是深度优先遍历(DFS),栈结构能完美模拟递归的深度优先遍历顺序,保证输出的层级结构和递归一致。

内容的提问来源于stack exchange,提问作者Steam Second

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:27:43