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?!?