Algorithm 单链表和双链表中删除的时间复杂度是多少?

Algorithm 单链表和双链表中删除的时间复杂度是多少?,algorithm,optimization,data-structures,time-complexity,computer-science,Algorithm,Optimization,Data Structures,Time Complexity,Computer Science,如果我们不知道节点的位置,那么单链表和双链表是否都需要O(n)时间才能删除 我的理解是,我们需要遍历到节点,以了解单链表中节点的上一个指针和下一个指针。因此,要删除的单链表的时间复杂度为O(n) 对于双链表,由于我们知道要删除的节点的上一个和下一个指针,时间复杂度是O(1)在这两种情况下定位节点都是O(n)(下面是伪代码,下面是所有情况): 只给定双链接列表中的节点的指针就可以删除该节点,这是O(1),因为您可以轻松访问上一个节点: def del (ptr): if ptr == h

如果我们不知道节点的位置,那么单链表和双链表是否都需要
O(n)
时间才能删除

我的理解是,我们需要遍历到节点,以了解单链表中节点的上一个指针和下一个指针。因此,要删除的单链表的时间复杂度为
O(n)

对于双链表,由于我们知道要删除的节点的上一个和下一个指针,时间复杂度是
O(1)

在这两种情况下定位节点都是
O(n)
(下面是伪代码,下面是所有情况):


只给定双链接列表中的节点的指针就可以删除该节点,这是
O(1)
,因为您可以轻松访问上一个节点:

def del (ptr):
    if ptr == head: # head is special case
        head = ptr.next
        free ptr
        return

    ptr.prev.next = ptr.next
    free ptr

对于那些相同的条件(仅具有指针),删除单链表中的节点是
O(n)
,因为您需要首先找到要删除的节点之前的节点:

def del (ptr):
    if ptr == head: # head is special case
        head = ptr.next
        free ptr
        return

    prev = head
    while prev.next != ptr:
        prev = prev.next
    prev.next = ptr.next
    free ptr
def del (key):
    if head == null: # no action on empty list
        return

    if head.key == key: # head is special case
        temp = head
        head = head.next
        free temp
        return

    prev = head
    while prev.next != null:
        if prev.next.key == key:
            temp = prev.next
            prev.next = temp.next
            free temp
            return
        prev = prev.next
然而,两个
O(n)
操作仍然是
O(n)
,因为它与节点数成线性关系

因此,删除一个你还没有指针指向的节点,在这两种情况下都是
O(n)
,如果你天真地删除了,那么每个
n
所做的工作对于单链表来说都会更大(比如“定位要删除的节点”然后“在该节点之前定位节点”)


但通常情况下,你不会这么做。您的delete函数将在前进时记住上一个节点,这样,一旦找到要删除的节点,您就可以在它之前找到该节点,这样您就不需要再次搜索

可能是这样的,我们实际上是在要删除的元素之前搜索该元素:

def del (ptr):
    if ptr == head: # head is special case
        head = ptr.next
        free ptr
        return

    prev = head
    while prev.next != ptr:
        prev = prev.next
    prev.next = ptr.next
    free ptr
def del (key):
    if head == null: # no action on empty list
        return

    if head.key == key: # head is special case
        temp = head
        head = head.next
        free temp
        return

    prev = head
    while prev.next != null:
        if prev.next.key == key:
            temp = prev.next
            prev.next = temp.next
            free temp
            return
        prev = prev.next

除了现有的答案之外,如果我们允许移动节点的内容,有一种方法可以在给定一个指向该节点的指针的恒定时间内从单链接列表中删除节点。我们将下一个节点的内容移动到要删除的节点中,并使指向下一个节点的指针指向下一个节点之后的节点