简体   繁体   English

c#中的双循环链表

[英]doubly-circular linked list in c#

I am using a doubly-circular linked list.我正在使用一个双循环链表。 After adding values I am retrieving values from the list.添加值后,我正在从列表中检索值。 I am using this code to add values:我正在使用此代码添加值:

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

I am giving the data as:我将数据提供为:

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

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

I am retrieving the list data as:我将列表数据检索为:

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

The problem is it is giving the value of current as null while retrieving the node value.问题是它在检索节点值时将current值设为null

The list is an example from stackoverflow itself.该列表是 stackoverflow 本身的一个示例。

Please help me..请帮我..

My whole linked list class is as:我的整个链表 class 如下:

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

If root == null when this is called, there's no reason for this function to work, it should be causing a stack overflow when it call itself over and over again...如果root == null当它被调用时,这个 function 没有理由工作,它应该在它一遍又一遍地调用自己时导致堆栈溢出......

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

So, if you're successfully calling it there seems to be three options:因此,如果您成功调用它,似乎有三个选项:

  • You've managed to configure your compiler optimizations so that it's removing the call (this seems unlikely, but I guess could be possible).您已经设法配置编译器优化,以便它删除调用(这似乎不太可能,但我想可能)。
  • You're never be calling it with root==null , which means something else is modifying root , possible since it's protected, however if the usage code you've provided is correct, this shouldn't be the case, since you don't mention a derived class.你永远不会用root==null调用它,这意味着其他东西正在修改root ,可能因为它受到保护,但是如果你提供的使用代码是正确的,那不应该是这种情况,因为你没有'没有提到派生的 class。
  • Your usage code is paraphrased and really you're calling add from within a try/catch block and ignoring the exception that's getting thrown.您的使用代码被解释了,实际上您是从 try/catch 块中调用 add 并忽略抛出的异常。

As I've said in my comment, removing the extra call to this.add(data) , should fix your problem (with populating the list), however, I'd suggest you step through the function calls in the debugger, so that you can see what's going on.正如我在评论中所说,删除对this.add(data)的额外调用应该可以解决您的问题(填充列表),但是,我建议您逐步完成调试器中的 function 调用,以便你可以看到发生了什么。 I'd be interest to know if it really calls the 'Add' function.我很想知道它是否真的调用了“添加”function。

As far as retrieving information from the list, the get function looks like it should work, assuming information has been put into the list correctly and you're calling get on the same list that the data was inserted into.就从列表中检索信息而言,get function 看起来应该可以工作,假设信息已正确放入列表中,并且您在插入数据的同一列表中调用 get。 Again, if it's not working, the debugger is your friend when trying to figure out which bit isn't populated the way you'd expect it to be.同样,如果它不工作,调试器是你的朋友,当你试图找出哪个位没有按照你期望的方式填充时。

As pointed out by @forsvarir: You should not call Add again when no root node exists.正如@forsvarir 所指出的:当不存在根节点时,您不应再次调用Add Just remove that call and everything will be fine.只需删除该呼叫,一切都会好起来的。

If I were you I would not add Indexer or a GetAt method to a LinkedList implementation.如果我是你,我不会将 Indexer 或GetAt方法添加到LinkedList实现中。 It's quite inefficient to use a linked list of you need to have index access.使用需要索引访问的链表是非常低效的。

Make your list implement IEnumerable instead and let the users use LINQ.让您的列表实现IEnumerable并让用户使用 LINQ。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM