diff --git a/data_structures/linked_list/middle_element_of_linked_list.py b/data_structures/linked_list/middle_element_of_linked_list.py index 86dad6b41d73..224f320e7b4e 100644 --- a/data_structures/linked_list/middle_element_of_linked_list.py +++ b/data_structures/linked_list/middle_element_of_linked_list.py @@ -2,67 +2,79 @@ class Node: + """Represents a node in the linked list.""" + def __init__(self, data: int) -> None: self.data = data self.next = None class LinkedList: - def __init__(self): + """Represents a linked list.""" + + def __init__(self) -> None: self.head = None + self.size = 0 # Keep track of the list size - def push(self, new_data: int) -> int: + def push(self, new_data: int) -> None: + """Adds a new node to the front of the list.""" new_node = Node(new_data) new_node.next = self.head self.head = new_node - return self.head.data + self.size += 1 # Increment the list size def middle_element(self) -> int | None: - """ - >>> link = LinkedList() - >>> link.middle_element() - No element found. - >>> link.push(5) - 5 - >>> link.push(6) - 6 - >>> link.push(8) - 8 - >>> link.push(8) - 8 - >>> link.push(10) - 10 - >>> link.push(12) - 12 - >>> link.push(17) - 17 - >>> link.push(7) - 7 - >>> link.push(3) - 3 - >>> link.push(20) - 20 - >>> link.push(-20) - -20 - >>> link.middle_element() - 12 - >>> - """ - slow_pointer = self.head - fast_pointer = self.head - if self.head: - while fast_pointer and fast_pointer.next: - fast_pointer = fast_pointer.next.next - slow_pointer = slow_pointer.next - return slow_pointer.data - else: + """Returns the middle element of the list.""" + if not self.head: print("No element found.") return None + slow_pointer = self.head + fast_pointer = self.head + while fast_pointer and fast_pointer.next: + fast_pointer = fast_pointer.next.next + slow_pointer = slow_pointer.next + return slow_pointer.data + + def __str__(self) -> str: + """Returns a string representation of the list.""" + nodes = [] + current = self.head + while current: + nodes.append(str(current.data)) + current = current.next + return " -> ".join(nodes) + + +def find_middle_element(linked_list: LinkedList) -> int | None: + """ + Algorithm: Find the Middle Element of a Linked List + + This algorithm uses the slow and fast pointer technique to find the middle element of a linked list. + + Time Complexity: O(n/2) = O(n) + Space Complexity: O(1) + + :param linked_list: The linked list to find the middle element of + :return: The middle element of the linked list, or None if the list is empty + """ + if not linked_list.head: + print("No element found.") + return None + + slow_pointer = linked_list.head + fast_pointer = linked_list.head + while fast_pointer and fast_pointer.next: + fast_pointer = fast_pointer.next.next + slow_pointer = slow_pointer.next + return slow_pointer.data + if __name__ == "__main__": link = LinkedList() - for _ in range(int(input().strip())): - data = int(input().strip()) + num_elements = int(input("Enter the number of elements: ")) + for _ in range(num_elements): + data = int(input("Enter element {}: ".format(_ + 1))) link.push(data) - print(link.middle_element()) + print("Linked List:", link) + print("Middle Element:", find_middle_element(link))