c#中的双循环链表

时间:2011-06-14 06:55:42

标签: c# list linked-list

我正在使用双循环链表。添加值后,我正在从列表中检索值。我正在使用此代码添加值:

public void Add(T data)
{
    if (root == null)
    {
        this.Add(data);
        root = new LinkedListNode<T>(data);
        last = root;
    }
    else
    {
        last.Next = new LinkedListNode<T>(data);
        last.Next.Previous = last;
        last = last.Next;
    }
}

我将数据提供为:

char[] dir = { 'n', 'w', 's', 'e' };
TestProject.classes.LinkedList<char> list = new TestProject.classes.LinkedList<char>();

foreach (char c in dir)
{
    list.Add(c);
}

我正在检索列表数据:

public LinkedListNode<T> GetAt(int index)
{
    var current = root;
    for (int i = 0; i < index; i++)
    {
        if (current == null)
            return null;
        current = current.Next;
    }
    return current;
}

问题是它在检索节点值时将current的值赋予null

该列表是stackoverflow本身的一个示例。

请帮帮我..

我的整个链表类如下:

public class LinkedList<T>
{
    protected LinkedListNode<T> root = null;
    protected LinkedListNode<T> last = null;
    public LinkedList()
    {
    }

    public string ToString()
    {
        StringBuilder sb = new StringBuilder();
        var node = root;
        while (node != null)
        {
            sb.Append("{ " + node.Data.ToString() + " } ");
            node = node.Next;
        }
        return sb.ToString();
    }

    public T this[int index]
    {
        get
        {
            var node = GetAt(index);
            if (node == null)
                throw new ArgumentOutOfRangeException();
            return node.Data;
        }
        set
        {
            var node = GetAt(index);
            if (node == null)
                throw new ArgumentOutOfRangeException();
            node.Data = value;
        }
    }

    public LinkedListNode<T> GetAt(int index)
    {
        var current = root;
        for (int i = 0; i < index; i++)
        {
            if (current == null)
                return null;
            current = current.Next;
        }
        return current;
    }

    public void Add(T data)
    {
        if (root == null)
        {
            this.Add(data);
            root = new LinkedListNode<T>(data);
            last = root;
        }
        else
        {
            last.Next = new LinkedListNode<T>(data);
            last.Next.Previous = last;
            last = last.Next;
        }
    }
}

public class LinkedListNode<T>
{
    public T Data { get; set; }

    public LinkedListNode(T data)
    {
        Data = data;
    }

    public LinkedListNode<T> Next { get; set; }
    public LinkedListNode<T> Previous { get; set; }
}

2 个答案:

答案 0 :(得分:1)

如果root == null调用它时,没有理由让这个函数工作,它应该在它反复调用时引起堆栈溢出......

public void Add(T data)
{
    if (root == null)
    {
        this.Add(data);  // recurse?!?

所以,如果你成功地调用它,似乎有三种选择:

  • 您已设法配置编译器优化,以便删除调用(这似乎不太可能,但我认为可能)。
  • 您永远不会使用root==null来调用它,这意味着其他内容正在修改root,因为它受到保护,但是如果您提供的使用代码是正确的,则不应该既然如此,因为你没有提到派生类。
  • 您的使用代码已被解释,您实际上是在try / catch块中调用add并忽略了被抛出的异常。

正如我在评论中所说,删除对this.add(data)的额外调用,应该解决您的问题(填充列表),但是,我建议您逐步调试调试器中的函数,这样你就可以看到发生了什么。我很想知道它是否真的称为“添加”功能。

就从列表中检索信息而言,get函数看起来应该有效,假设信息已正确放入列表中,并且您正在调用get插入数据的相同列表。同样,如果它不起作用,调试器是你的朋友,试图找出未按照你预期的方式填充哪个位。

答案 1 :(得分:0)

正如@forsvarir所指出的:当没有根节点存在时,不应该再次调用Add。只需删除该电话,一切都会好的。

如果我是你,我不会在GetAt实施中添加Indexer或LinkedList方法。使用您需要拥有索引访问权限的链表是非常低效的。

改为使列表实现IEnumerable,让用户使用LINQ。