C# 将After/Before插入已排序的LinkedList大O复杂度

C# 将After/Before插入已排序的LinkedList大O复杂度,c#,algorithm,sorting,linked-list,binary-search-tree,C#,Algorithm,Sorting,Linked List,Binary Search Tree,在c#中,我们有LinkedList库,它有一些有用的方法。其中一个是AddAfter/AddBefore方法。我认为在排序的LinkedList中,如果使用二进制搜索,那么它的复杂性是O(log(n)) 我说得对吗?或者你能更准确地解释一下吗?请看一下实现。这两种方法与搜索无关。所以,它是O(1) public void AddAfter(LinkedListNode节点,LinkedListNode新节点){ 验证节点; ValidateNewNode(newNode); InternalI

在c#中,我们有LinkedList库,它有一些有用的方法。其中一个是AddAfter/AddBefore方法。我认为在排序的LinkedList中,如果使用二进制搜索,那么它的复杂性是O(log(n))


我说得对吗?或者你能更准确地解释一下吗?请看一下实现。这两种方法与搜索无关。所以,它是O(1)

public void AddAfter(LinkedListNode节点,LinkedListNode新节点){
验证节点;
ValidateNewNode(newNode);
InternalInsertNodeBefore(node.next,newNode);
newNode.list=this;
}  
public void AddBefore(LinkedListNode节点,LinkedListNode新节点){
验证节点;
ValidateNewNode(newNode);
InternalInsertNodeBefore(节点,新节点);
newNode.list=this;
如果(节点==头部){
头=新节点;
}
}
私有void InternalInsertNodeBefore(LinkedListNode节点,LinkedListNode新节点){
newNode.next=节点;
newNode.prev=node.prev;
node.prev.next=newNode;
node.prev=newNode;
版本++;
计数++;
}

看一下实现。这两种方法与搜索无关。所以,它是O(1)

public void AddAfter(LinkedListNode节点,LinkedListNode新节点){
验证节点;
ValidateNewNode(newNode);
InternalInsertNodeBefore(node.next,newNode);
newNode.list=this;
}  
public void AddBefore(LinkedListNode节点,LinkedListNode新节点){
验证节点;
ValidateNewNode(newNode);
InternalInsertNodeBefore(节点,新节点);
newNode.list=this;
如果(节点==头部){
头=新节点;
}
}
私有void InternalInsertNodeBefore(LinkedListNode节点,LinkedListNode新节点){
newNode.next=节点;
newNode.prev=node.prev;
node.prev.next=newNode;
node.prev=newNode;
版本++;
计数++;
}

AddBefore
AddAfter
接受一个
LinkedListNode
作为第一个参数,该节点是将添加新节点之前/之后的节点。此操作是
O(1)

遍历(枚举)链接列表是一个O(n)操作,因为要查看第x个节点,必须遍历x-1个节点。不能对
链接列表进行二进制搜索,因为不遍历第x个元素就无法直接访问它


因此,如果要将新节点添加到保持有序的
LinkedList
,首先必须遍历它以找到插入新元素的“正确”位置(O(n)操作),然后必须使用
AddBefore
AddAfter
(O(1)操作)插入它。复合复杂度显然是O(n)。

AddBefore
AddAfter
接受一个
LinkedListNode
作为第一个参数,该节点是将添加新节点之前/之后的节点。此操作是
O(1)

遍历(枚举)链接列表是一个O(n)操作,因为要查看第x个节点,必须遍历x-1个节点。不能对
链接列表进行二进制搜索,因为不遍历第x个元素就无法直接访问它


因此,如果要将新节点添加到保持有序的
LinkedList
,首先必须遍历它以找到插入新元素的“正确”位置(O(n)操作),然后必须使用
AddBefore
AddAfter
(O(1)操作)插入它。复合复杂性显然是O(n)。

二进制搜索只能用于已排序的集合,而insert中的链表复杂性(insert first除外)是O(n)。告诉您复杂性是O(1)。是的,insert在集合中的复杂性是O(1),但如果要在特定值之后插入,复杂性是多少?例如:SortedLinkedList:[2,5,7,11,14],我想在后面插入8,基本上在后面11@Lee但事实并非如此sorted@Boo为什么是O(n)你能解释一下吗?如果我做二元搜索,二元搜索只能用于已排序的集合,而insert中的链表复杂性(insert first除外)为O(n)。告诉您复杂性为O(1)。是的,insert在集合中的复杂性为O(1),但如果您想在特定值之后插入,复杂性是多少?例如:SortedLinkedList:[2,5,7,11,14],我想在后面插入8,基本上在后面11@Lee但事实并非如此sorted@Boo为什么是O(n)你能解释一下吗?如果我做二进制搜索是的,我知道它在未排序的LinkedList中是O(1),但在排序的LinkedList中呢?排序与否并不重要,因为它永远不会搜索。是的,我知道它在未排序的LinkedList中是O(1),但在排序的LinkedList中呢?排序与否并不重要,因为它永远不会搜索。
public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode) {
    ValidateNode(node);
    ValidateNewNode(newNode);
    InternalInsertNodeBefore(node.next, newNode);
    newNode.list = this;
}  

public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode) {
    ValidateNode(node);    
    ValidateNewNode(newNode);                        
    InternalInsertNodeBefore(node, newNode);
    newNode.list = this;
    if ( node == head) {
        head = newNode;
    }
}

private void InternalInsertNodeBefore(LinkedListNode<T> node, LinkedListNode<T> newNode) {
    newNode.next = node;
    newNode.prev = node.prev;
    node.prev.next = newNode;
    node.prev = newNode;            
    version++;
    count++;
}