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

时间:2019-05-19 09:36:09

标签: algorithm optimization data-structures time-complexity computer-science

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

我的理解是,我们需要遍历node才能知道单链表中该节点的上一个指针和该节点的下一个指针。因此,删除单个链接列表的时间复杂度为O(n)

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

2 个答案:

答案 0 :(得分:5)

在两种情况下,O(n)定位一个节点(此处为伪代码,在以下所有情况下为伪代码):

def locate(key):
    ptr = head
    while ptr != null:
        if ptr.key == key:
            return ptr
        ptr = ptr.next
    return null

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

但是,两个O(n)操作仍然是 O(n),因为它线性依赖于节点数。

因此,要删除尚无指针的节点,在两种情况下都为O(n),对于单个链接列表,只是每个n所做的工作都会更大,如果您是天真的话(例如“查找要删除的节点”,然后“查找该节点之前的节点”)。


尽管通常,您不会这样做。您的delete函数会在前进时记住上一个节点,这样,一旦找到要删除的节点,您还将在前一个节点,这样就不必 进行另一次搜索。

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

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

答案 1 :(得分:0)

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