Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
删除c#链表中的操作_C#_Linked List - Fatal编程技术网

删除c#链表中的操作

删除c#链表中的操作,c#,linked-list,C#,Linked List,我对链表中的c#remove操作有一个问题LinkedListNode是不可变的,但是Remove(LinkedListNode)是固定时间。为什么我对它有问题?原因如下: 通常,在删除时,我会编写以下代码(忘记空值): public void删除(LinkedListNode) { node.Previous.Next=node.Next; node.Next.Previous=node.Previous; } 但由于LinkedListNode是不可变的,因此这不是一个选项。那么它是如何在

我对链表中的c#remove操作有一个问题
LinkedListNode
是不可变的,但是
Remove(LinkedListNode)
是固定时间。为什么我对它有问题?原因如下:

通常,在删除时,我会编写以下代码(忘记空值):

public void删除(LinkedListNode)
{
node.Previous.Next=node.Next;
node.Next.Previous=node.Previous;
}

但由于
LinkedListNode
是不可变的,因此这不是一个选项。那么它是如何在O(1)时间内完成的呢?

它不是不可变的,但是那些属性是只读的

//Out of LinkListNode<T>:

public LinkedListNode<T> Next {
    get { return next == null || next == list.head? null: next;} //No setters
}

public LinkedListNode<T> Previous {
    get { return prev == null || this == list.head? null: prev;} //No setters
}

在内部,LinkedList(T)的删除方法依赖于:

internal void InternalRemoveNode(LinkedListNode<T> node)
内部无效InternalRemoveNode(LinkedListNode节点)
反过来,它本身直接操作LinkedListNode(T)的相应支持字段,这两个字段也用声明:

internal LinkedListNode<T> prev;
internallinkedListNode-prev;

下一步是内部LinkedListNode;

'希望这有帮助,

为什么不使用?我假设您所指的
LinkedListNode
是?@RafaelCardoso嗯,它不是。这个类只提供上一个和下一个的getter。@EdPlunkett我在使用上没有问题。我知道我可以。我的问题是不同的——正如我所写的——它是如何在O(1)时间内工作的?啊,好的。我猜他们只是在实现中偷偷地更新私有字段。非常确定所有这些东西的源代码现在都可用。是的,吉拉德·格林在我输入评论之前的一次更新中就有了它。@sm21-检查我的最新更新-我已经添加了.Net使用的代码,这就是我想要的答案。谢谢
public bool Remove(T value) {
    LinkedListNode<T> node = Find(value);
    if (node != null) {
        InternalRemoveNode(node);     //  <==============
        return true;
    }
    return false;
}

public void Remove(LinkedListNode<T> node) {
    ValidateNode(node);          
    InternalRemoveNode(node);         //  <==============
}

internal void InternalRemoveNode(LinkedListNode<T> node) {
    Debug.Assert( node.list == this, "Deleting the node from another list!");   
    Debug.Assert( head != null, "This method shouldn't be called on empty list!");
    if ( node.next == node) {
        Debug.Assert(count == 1 && head == node, "this should only be true for a list with only one node");
        head  = null;
    } 
    else {
    /******************** Relevant part here *****************/
        node.next.prev = node.prev;
        node.prev.next = node.next;
        if ( head == node) {
            head = node.next;
        }
    }
    node.Invalidate();  
    count--;
    version++;          
}
internal LinkedListNode<T> next;
internal LinkedListNode<T> prev;
internal void InternalRemoveNode(LinkedListNode<T> node)
internal LinkedListNode<T> prev;
internal LinkedListNode<T> next;