In this article, we will learn what is singly linked list is and its implementation using Python.
The singly linked list is a linear data structure in which each element of the list contains a pointer that points to the next element in the list. Each element in the singly linked list is called a node. Each node has two components: data and a pointer next which points to the next node in the list.
The first node of the list is called a head, and the last node of the list is called a tail. The last node of the list contains a pointer to the null. Each node in the list can be accessed linearly by traversing through the list from head to tail.
Singly Linked List Implementation in Python
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})" class LinkedList: def __init__(self): self.head = None def __iter__(self) -> Any: node = self.head while node: yield node.data node = node.next def __len__(self) -> int: return len(tuple(iter(self))) def __repr__(self) -> str: return "->".join([str(item) for item in self]) def __getitem__(self, index: int) -> Any: if not 0 <= index < len(self): raise ValueError("list index out of range.") for i, node in enumerate(self): if i == index: return node # Used to change the data of a particular node def __setitem__(self, index: int, data: Any) -> None: if not 0 <= index < len(self): raise ValueError("list index out of range.") current = self.head for i in range(index): current = current.next current.data = data def insert_tail(self, data: Any) -> None: self.insert_nth(len(self), data) def insert_head(self, data: Any) -> None: self.insert_nth(0, data) def insert_nth(self, index: int, data: Any) -> None: if not 0 <= index <= len(self): raise IndexError("list index out of range") new_node = Node(data) if self.head is None: self.head = new_node elif index == 0: new_node.next = self.head # link new_node to head self.head = new_node else: temp = self.head for _ in range(index - 1): temp = temp.next new_node.next = temp.next temp.next = new_node def print_list(self) -> None: # print every node data print(self) def delete_head(self) -> Any: return self.delete_nth(0) def delete_tail(self) -> Any: # delete from tail return self.delete_nth(len(self) - 1) def delete_nth(self, index: int = 0) -> Any: if not 0 <= index <= len(self) - 1: # test if index is valid raise IndexError("List index out of range.") delete_node = self.head # default first node if index == 0: self.head = self.head.next else: temp = self.head for _ in range(index - 1): temp = temp.next delete_node = temp.next temp.next = temp.next.next return delete_node.data def is_empty(self) -> bool: return self.head is None def reverse(self) -> None: prev = None current = self.head while current: # Store the current node's next node. next_node = current.next # Make the current node's next point backwards current.next = prev # Make the previous node be the current node prev = current # Make the current node the next node (to progress iteration) current = next_node # Return prev in order to put the head at the end self.head = prev def main(): linked_list = LinkedList() linked_list.insert_head(input("Inserting 1st at head ").strip()) linked_list.insert_head(input("Inserting 2nd at head ").strip()) print("\nPrint list:") linked_list.print_list() linked_list.insert_tail(input("\nInserting 1st at tail ").strip()) linked_list.insert_tail(input("Inserting 2nd at tail ").strip()) print("\nPrint list:") linked_list.print_list() print("\nDelete head") linked_list.delete_head() print("Delete tail") linked_list.delete_tail() print("\nPrint list:") linked_list.print_list() print("\nReverse linked list") linked_list.reverse() print("\nPrint list:") linked_list.print_list() print("\nString representation of linked list:") print(linked_list) print("\nReading/changing Node data using indexing:") print(f"Element at Position 1: {linked_list[1]}") linked_list[1] = input("Enter New Value: ").strip() print("New list:") print(linked_list) print(f"length of linked_list is : {len(linked_list)}") if __name__ == "__main__": main()
Output:
Inserting 1st at head 10 Inserting 2nd at head 20 Print list: 20->10 Inserting 1st at tail 30 Inserting 2nd at tail 40 Print list: 20->10->30->40 Delete head Delete tail Print list: 10->30 Reverse linked list Print list: 30->10 String representation of linked list: 30->10 Reading/changing Node data using indexing: Element at Position 1: 10 Enter New Value: 50 New list: 30->50 length of linked_list is : 2
Related Data Structures in Python
Stack Implementation in PythonQueue Implementation in Python
Deque Implementation in Python
Singly Linked List Implementation in Python
Doubly Linked List Implementation in Python
Circular Linked List Implementation in Python
PriorityQueue Implementation in Python
Circular Queue Implementation in Python
Binary Search Tree Implementation in Python
Stack Implementation Using Linked List in Python
Stack Implementation Using Doubly Linked List in Python
DSA Python
Comments
Post a Comment