需要帮助为c#中的链表制作枚举器
本文关键字:链表 枚举 帮助 | 更新日期: 2023-09-27 18:15:00
我试图采取一个自定义的链表类,我做了一个枚举器在我的一个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()
{
}
}
迭代器块使创建实现IEnumerable<T>
的对象变得更加容易:
public static IEnumerable<T> Iterate<T>(Node<T> root)
{
var current = root;
while (current != null)
{
yield return current.getData();
current = current.getNext();
}
}
它删除了大部分样板代码,只允许您定义用于确定序列中节点是什么的所有逻辑,同时仍然提供编写所有代码的所有功能。
在c#世界中,这个概念被称为枚举而不是迭代。不要与enum
混淆
无论如何,您正在寻找的各自的接口是System.Collections.Generic
命名空间中的IEnumerable<T>
和IEnumerator<T>
。检查一下他们的文档,你就可以了。这个概念本身与您在Java中所做的非常相同。
linkedlist的枚举符应该是这样的:
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 +不要忘记构造函数。
我不知道你的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纠正了我。谢谢!
我可能还是会建议修改一些名称来澄清操作。:)