If we don't know the position of the node, is it true that both singly linked list and doubly linked list take O(n)
time to delete?
My understanding is that we need to traverse to node to know the previous pointer of the node and next pointer of node in singly linked list. The time complexity for singly linked list to delete is O(n)
as a result.
For doubly linked list, since we know the previous and next pointers of the node we want to delete, the time complexity is O(1)
.
It's O(n)
to locate a node in both cases (pseudo-code follows here, and in all cases below):
def locate(key):
ptr = head
while ptr != null:
if ptr.key == key:
return ptr
ptr = ptr.next
return null
It's O(1)
to delete a node in a doubly linked list given only its pointer, because you can get to the previous node easily:
def del (ptr):
if ptr == head: # head is special case
head = ptr.next
free ptr
return
ptr.prev.next = ptr.next
free ptr
For those same conditions (only having the pointer), it's O(n)
to delete a node in a singly linked list because you need to first locate the node before the one you want to 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
However, two O(n)
operations is still O(n)
since it's linearly dependent on the number of nodes.
Hence, to delete a node you don't yet have a pointer to, is O(n)
in both cases, it's just the work done for each n
would be bigger for the singly linked list, if you did it naively (as "locate node to delete" then "locate node before that one").
Typically though, you wouldn't do that. Your delete function would remember the previous node when advancing so that, once you'd found the one to delete, you also have the one before it so you wouldn't need another search.
That could go something like this, with us actually searching for the element before the one you want to 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