不能直接用for-each遍历二叉树或图,是因为它们未实现Iterable接口;需手动实现迭代器,用栈模拟递归过程以支持深度优先遍历。
不能直接用 for-each 遍历二叉树或图,是因为它们没实现 iterable 接口——缺少 iterator() 方法。java 的增强 for 循环只认这个契约,否则抛出 classcastexception。要支持深度优先遍历,就得手动提供一个迭代器,把递归逻辑“翻译”成栈驱动的状态机。
递归本质是系统自动维护调用栈:每层压入参数、局部变量和返回地址;终止后从栈顶逐层弹出。深度优先遍历天然依赖这种“后进先出”顺序。自定义迭代器不能依赖方法调用栈(会溢出、不可控),所以必须显式用 Stack 或 Deque 模拟整个过程。
以二叉树中序遍历为例,关键不是“怎么写循环”,而是“怎么管理状态”:
hasNext() 只查栈是否为空:不预计算下一个元素,保持轻量;空栈即遍历结束next() 弹出栈顶,立即压入其右子树的最左路径:比如弹出节点 A,若 A 有右子树,则从 A.right 开始一路向左压栈,确保下一次 next() 返回的是 A 右子树中最靠左的节点图比树更复杂:可能有环、多起点、无固定根。深度优先迭代器需额外处理:
Set<Node> 记录已访问节点,防止重复入栈陷入死循环getNeighbors(node) 动态获取,每次弹出节点后将其未访问邻居全部压栈一个树类如果同时提供前序、中序、后序的 iterator() 方法,容易导致状态混乱、难以测试。推荐做法是:
Iterator 子类(如 InorderIterator、PreorderIterator)inOrderIterator()、preOrderIterator()