需要帮助为c#中的链表制作枚举器

问题描述 投票:4回答:4

我正在尝试使用我制作的自定义链表列表,并在我的一个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()
    {
    }
}
c# enumeration singly-linked-list
4个回答
3
投票

迭代器块使创建实现IEnumerable<T>的对象变得更加容易:

public static IEnumerable<T> Iterate<T>(Node<T> root)
{
    var current = root;
    while (current != null)
    {
        yield return current.getData();
        current = current.getNext();
    }
}

它删除了大多数样板代码,只是让你定义所有逻辑来确定序列中的节点是什么,同时仍然提供所有功能,就像你所做的那样写出所有代码。


0
投票

在C#世界中,这个概念称为枚举而不是迭代。不要与enum混淆。

无论如何,您正在寻找的各个接口是IEnumerable<T>命名空间中的IEnumerator<T>System.Collections.Generic。查看他们的文档,你应该很高兴。这个概念本身与你在Java中所做的完全相同。


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纠正了我。谢谢!

我可能仍会建议更改一些名称来澄清操作。 :)


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。

© www.soinside.com 2019 - 2024. All rights reserved.