双向链接列表可以实现链接列表的惯用遍历,我想为什么不能使用二叉树?传统上,二进制树或树一般是单向的,这意味着,给定一个具有足够数量节点的大树,找到叶节点的运行时间可能是昂贵的。
如果找到这样一个节点后,找到下一个我可以将树遍历回根,那么与通过树的每个节点的另一个深度优先搜索相比,这是不是有利的吗?我之前从未考虑过这一点,直到认识到双重链表和二叉树的结合可能会增加利益。
例如,如果我使用内部类
class Tree<T> {
private class TwoWayNode {
var data : T
var left : TwoWayNode
var right : TwoWayNode
var previous : TwoWayNode
}
}
左和右的使用与从每个节点遍历各个子树一样正常,并且之前将保持指向父节点启用惯用遍历的指针。像这样的人会很好地工作,有什么潜在的问题或陷阱吗?
答案 0 :(得分:1)
鉴于您存储了previous
引用,您可以先走最左边。到达叶子节点后,再次向上移动,向右移动。
您始终可以将当前节点,您的&#34; walker&#34;与子节点进行比较,以便检查您是否 left 或< em>对最后一次。这使你的遍历无状态,你甚至不需要递归;适用于非常大的数据集。
现在,每次你离开右边的叶子,你都会再次向后退一个。
此算法是Depth-First-Search。 *
加快速度: 鉴于您可以为遍历顺序定义一些确定性条件,这可以变得非常灵活,甚至可以用于光线跟踪等应用程序。
* :http://en.wikipedia.org/wiki/Depth-first_search
Bonus:本文介绍了光线跟踪中Kd树的遍历算法:评论:光线跟踪的Kd树遍历算法(http://dcgi.felk.cvut.cz/home/havran/ARTICLES)/cgf2011.pdf
答案 1 :(得分:0)
实际上,二叉树的节点通常使用指向 left 和 right 子节点以及 parent 的指针来实现(请参阅{{3}红黑树)。
但你并不总是需要一个父指针:
超酷: Self adjusting binary search trees二进制搜索树,以便在没有堆栈的情况下遍历,从而更轻松地进行顺序(和反向顺序) - 所以O(1)空间! < / p>