C# c语言中的双循环链表#

C# c语言中的双循环链表#,c#,list,linked-list,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<

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

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;
    }
}

正如@forsvarir所指出的:当不存在根节点时,不应该再次调用
Add
。只要去掉那个电话,一切都会好起来的

如果我是你,我不会在
LinkedList
实现中添加索引器或
GetAt
方法。使用一个链接列表是非常低效的,因为你需要有索引访问权限


让您的列表实现
IEnumerable
,让用户使用LINQ。

如果调用此函数时
root==null
,则此函数没有理由工作,当它一次又一次地调用自身时,应该会导致堆栈溢出

public void Add(T data)
{
    if (root == null)
    {
        this.Add(data);  // recurse?!?
因此,如果您成功地调用它,似乎有三种选择:

  • 您已经成功地配置了编译器优化,以便删除调用(这似乎不太可能,但我想可能是可能的)
  • 您永远不会使用
    root==null
    调用它,这意味着其他东西正在修改
    root
    ,这是可能的,因为它是受保护的,但是如果您提供的使用代码是正确的,就不应该这样,因为您没有提到派生类
  • 您的使用代码已被解释,实际上您正在从try/catch块中调用add,并忽略抛出的异常
正如我在评论中所说,删除对
this.add(data)
的额外调用应该可以解决您的问题(填充列表),但是,我建议您在调试器中逐步完成函数调用,以便查看发生了什么。我很想知道它是否真的调用了“Add”函数


至于从列表中检索信息,get函数看起来应该可以工作,假设信息已正确地放入列表中,并且您正在插入数据的同一列表上调用get。同样,如果调试器不起作用,那么当您试图找出哪个位没有按预期的方式填充时,调试器就是您的朋友。

这不是:
public void Add(t data){if(root==null){this.Add(data);
临时递归(即堆栈溢出)?您一次又一次地重复调用同一个函数…root没有理由在调用之间发生更改…@forsvarir:但是当我从“public LinkedListNode GetAt(int index)”检索数据时,该值正在更改函数..当前值为空..@kawade您是否在构造函数中初始化
root
?您是否将
last
设置为相同的值?@forsvarir:不,我没有初始化CUNstructure中的任何内容?是否可以发布列表类的其余部分?
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 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; }
}
public void Add(T data)
{
    if (root == null)
    {
        this.Add(data);  // recurse?!?