如果我们不知道节点的位置,那么单链列表和双链列表是否都需要O(n)
的删除时间?
我的理解是,我们需要遍历node才能知道单链表中该节点的上一个指针和该节点的下一个指针。因此,删除单个链接列表的时间复杂度为O(n)
。
对于双向链表,由于我们知道要删除的节点的上一个指针和下一个指针,因此时间复杂度为O(1)
。
答案 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)
除了现有的答案外,如果我们允许移动节点的内容,那么只要给定指向它的指针,还有一种方法可以从单链列表常量时间删除该节点。我们将下一个节点的内容移动到要删除的节点中,并使指向下一个节点的指针指向下一个节点之后的节点。