Linked List
Similar to the array, the linked list is also a linear data structure. And each element in the linked list is actually a separate object while all the objects are linked together by the reference field in each element.
There are two types of linked list: singly linked list and doubly linked list.
The skills for Linked list
- Structure of singly linked list and doubly linked list;
- Implement traversal, insertion, deletion in a singly or doubly linked list;
- Analyze the complexity of different operations;
- Two-pointer technique in the linked list;
- Solve the classic problems such as reverse a linked list;
Singly Linked List
Each node contains not only the value but also a reference field to link to the next node.
Node Structure
We use the head node head to represent the whole list.
from typing import Any
class Node:
def __init__(self, data: Any):
self.data=data
self.next=None
def __repr__(self)-> str:
return f"Node({self.data})"
Operations
We are not able tp access a random element in a singly-linked list in constant time. If we want get the ith element, we have to traverse from the head node one by one. It takes O(N) time on average to visit an element by index, where N is the length of the linked list.
Add
- unlike an array, we don’t need to move all elements past the inserted element.
- new value
- linked the “next” field of new value to prev’s next node
- link the “next” field in
prevto the new value
addAtHead O(1)add a node at the beginning- we use the head node
headto represent the whole list, so it is essential to updateheadwhen adding a new node at the beginning of the list. - initialize a new node
cur - lind the new node to our original head node
head - assign
curtohead
- we use the head node
addAtTail(int val) O(n)append a node as the last element of the linked list- we get the head node
- iterator the linked-list to get the node in the end or the specify node(index)
- replace the
node.nextequal to the new node
addAtIndex(int index, int val)- add a node of value before the
indexnode in the linked list.O(index-1) - If
indexequals the length of the linked list, the node will be append to the end of the linked list.O(n) n=len(linked_list) - If
indexis greater than the length, the node will not be inserted
- add a node of value before the
Delete
- delete the node
curcan do it in two stepsO(index)- find cur’s previous node
prevand its next nodenext; - link
prevto cur’s node next
- find cur’s previous node
It is easy to find out next using the reference field of cur. However, we have to traverse the linked list from the head node to find out prev which will take O(N) time on average, N is the length of the linked list.
The space complexity is O(1) because we only need constant space to store our pointers.
- delete the first node
- assign the next node too head
- delete the last node
- we get the head node
- iterator the whole linked-list in order to get the node in the end
- let the node ahead of the last node as the last node
node.next=node.next.next
Traverse
- we can implement iterator to support traverse
def __iter__(self) -> Any:
node=self.head
while node:
yield node.data
node=node.next
Implement Linked-List
### Source to read: