我正在尝试使用我制作的自定义链表列表,并在我的一个C#程序中使用枚举器。我不想展示太多的代码,所以希望这已经足够了。
我不确定,但这是枚举器应该是什么样的?
class SinglyLinkedListEnumerator<T> : IEnumerator<T>
{
private Node<E> node;
private Node<E> start;
public SinglyLinkedListEnumerator(Node<T> node)
{
this.node = node;
start = node;
}
public T Current
{
get { return node.getData(); }
}
public Boolean MoveNext()
{
if (node.getNext() != null)
{
node = node.getNext();
return true;
}
return false;
}
public void Reset()
{
node = start;
}
public void IDisposable.Dispose()
{
}
}
答案 0 :(得分:3)
Iterator块使创建一个对象更容易实现IEnumerable<T>
:
public static IEnumerable<T> Iterate<T>(Node<T> root)
{
var current = root;
while (current != null)
{
yield return current.getData();
current = current.getNext();
}
}
它删除了大多数样板代码,只是让你定义所有逻辑来确定序列中的节点是什么,同时仍然提供了所有的功能,就像你一样写出了所有的代码。 / p>
答案 1 :(得分:0)
在C#世界中,这个概念被称为枚举而不是迭代。不要与enum
混淆。
无论如何,您要查找的各个接口在IEnumerable<T>
命名空间中为IEnumerator<T>
和System.Collections.Generic
。查看他们的文档,你应该很高兴。这个概念本身与你在Java中所做的完全相同。
答案 2 :(得分:0)
我不知道您的Node<T>
代码是什么样的,但这看起来很奇怪:
public Boolean MoveNext()
{
if (node.getNext() != null)
{
node = node.getNext();
return true;
}
return false;
}
理想情况下,看起来MoveNext看起来像这样:
public Boolean MoveNext()
{
// make sure current node is not null
if (node != null)
{
node = node.getNext();
}
// simply return whether current node is null or not
return node != null;
}
在您的初始方法中,您将获得两次可能给您错误结果的下一个节点。我假设getNext
只返回对当前节点的下一个兄弟的引用。否则,我没有看到您的枚举器(或迭代器)类的任何初始问题。
为清楚起见,我会使用currentNode
代替node
,并将start
更改为startNode
。 此外,如果 node.getNext()
未返回Node对象,则应重命名该方法以指示它正在执行的操作。
我假设node.getNext()
正在移动内部参考,但@Servy纠正了我。谢谢!
我可能仍会建议更改名称以澄清操作。 :)
答案 3 :(得分:0)
链接列表的枚举器应如下所示:
public class MyLinkedList : IEnumerable {
Node head = null;
Node current = null;
public IEnumerator GetEnumerator()
{
current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
虽然节点本身
public class Node
{
public int Data;
public Node Next;
public Node(int value) { Data = value; }
}
对于二叉树,您应该实现以下三种方法:Current,MoveNext和Reset +不要忘记Constructor。