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(' ', $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>"; }
代码逻辑解释
- 栈初始化:把根分类节点和初始层级(0)压入栈中。
- 循环处理栈元素:只要栈不为空,就弹出栈顶元素:
- 打印当前分类,用层级控制缩进,让嵌套结构更直观。
- 如果当前分类有子分类,逆序压入栈:因为栈是“后进先出”的结构,逆序压入后,弹出时会按照原顺序处理子分类,和递归的遍历顺序保持一致。
- 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
相关产品推荐
相关产品推荐

