I do not quiet understand why deleting at the end of a single linked list goes in O(1) time, as the wikipedia article says.
A single linked list consists out of node
Yes, you can do this in O(1) time even if you're not maintaining a pointer to the "previous element".
Let's say you have this list, where "head" and "tail" are static pointers, and "End" is a node marked as an end. You can use "next == NULL" as normal, but in this case you have to disregard the value:
head -> 1 -> 2 -> 3 -> 4 -> 5 -> End <- tail
Now, you're given a pointer to node 3, but not its previous node. you have the head and tail pointers too. Here's some python-ish code, assuming a SingleLinkedList class.
class SingleLinkedList:
# ... other methods
def del_node(self, node): # We "trust" that we're only ever given nodes that are in this list.
if node is self.head:
# Simple case of deleting the start
self.head = node.next
# Free up 'node', which is automatic in python
elif node.next is self.tail
# Simple case of deleting the end. This node becomes the sentinel
node.value = None
node.next = None
# Free up 'self.tail'
self.tail = node
else:
# Other cases, we move the head's value here, and then act
# as if we're deleting the head.
node.value = self.head.value
self.head = self.head.next
new_head = self.head.next
# Free up 'self.head'
self.head = new_head
Alas, this reorders the list, and moves values around, which may or may not be okay for your application.
O(1) simply means "constant cost". It does not mean 1 operation. It means "at most C" operations with C being fixed regardless of other parameters changing (such as list size). In fact, in the sometimes confusing world of big-Oh: O(1) == O(22).
By contrast deleting the whole list has O(n) cost, because the cost changes with the size (n) of the list.