【发布时间】:2016-06-29 16:51:37
【问题描述】:
在构建了一个由 BSTNode<Tkey,TValue> 节点组成的二叉搜索树 BST<Tkey,TValue> 之后,我正在尝试为其实现 IEnumerable 接口。
这就是我构造BSTNodeEnumrator<Tkey,TValue>的方式:
public class BSTNodeEnumerator<TKey, TValue> : IEnumerator<BSTNode<TKey, TValue>> where TKey : IComparable<TKey>
{
private Stack<BSTNode<TKey, TValue>> _stack;
public BSTNodeEnumerator(BSTNode<TKey, TValue> root)
{
_stack = new Stack<BSTNode<TKey, TValue>>();
_current = null;
_root = root;
}
// ... rest of the implementation
}
我传入root节点,_current是枚举的结果。我也在尝试为此使用堆栈,因为我没有像 AVL BST 那样跟踪父节点。
现在我希望枚举器以非递归方式按顺序 + 遍历树。由于 bst 的属性,这也应该导致排序枚举,这很好,因为这正是我想要实现的。
伪代码中顺序遍历的非递归算法,如wikipedia article
iterativeInorder(node)
s ← empty stack
while (not s.isEmpty() or node ≠ null)
if (node ≠ null)
s.push(node)
node ← node.left
else
node ← s.pop()
visit(node)
node ← node.right
我们可以把算法转换成这段c#代码:
public BSTNode<Tkey,TValue> Next()
{
while (_stack.Count > 0 || _current != null)
{
if (_current != null)
{
_stack.Push(_current);
_current = _current.left;
}
else
{
_current = _stack.Pop();
BSTNode<Tkey,TValue> result = _current;
_current = _current.Right;
}
}
return result;
}
但这不是必需的bool MoveNext() 实现,因为我必须返回一个布尔值。如果我确实将_current 设置为适当的节点,则为真,如果我在最后,则为假。
我应该如何实施 public bool MoveNext() ?我无法理解的主要事情是,如果我想将BSTNode<Tkey,TValue> Next() 转换为bool MoveNext(),我必须return true 而不是简单地访问节点BSTNode<Tkey,TValue> result = _current;,并且只有在那之后设置_current = _current.Right;我显然做不到。
【问题讨论】:
-
为什么不直接使用 HashSet 或 Dictionary 呢?
-
你需要自己制作IEnumerator吗?为什么不只是让您的 GetEnumerator 函数返回您的实现,而是在
BSTNode<Tkey,TValue> result = _current;行上执行yield return _current;。我将发布一个实施作为答案。 -
@MatthewWhited - 当然我可以简单地使用 .Net 中已有的内容,我只是想学习。到目前为止,我还在与 AVL 二叉树和跳过列表作斗争。我相信这是可以理解的。我的意思是 .Net 不只是从天而降。
-
阅读@ScottChamberlain 评论。迭代器方法和
yield语句是专门为非平凡的枚举器制作的。
标签: c# algorithm binary-search-tree ienumerable enumerator