|
6 | 6 |
|
7 | 7 | class Node:
|
8 | 8 | def __init__(self, data: Any):
|
| 9 | + """ |
| 10 | + Initialize a new Node with the given data. |
| 11 | + Args: |
| 12 | + data: The data to be stored in the node. |
| 13 | + """ |
9 | 14 | self.data: Any = data
|
10 |
| - self.next: Node | None = None |
| 15 | + self.next: Node | None = None # Reference to the next node |
11 | 16 |
|
12 | 17 |
|
13 | 18 | class CircularLinkedList:
|
14 |
| - def __init__(self): |
15 |
| - self.head = None |
16 |
| - self.tail = None |
| 19 | + def __init__(self) -> None: |
| 20 | + """ |
| 21 | + Initialize an empty Circular Linked List. |
| 22 | + """ |
| 23 | + self.head: Node | None = None # Reference to the head (first node) |
| 24 | + self.tail: Node | None = None # Reference to the tail (last node) |
17 | 25 |
|
18 | 26 | def __iter__(self) -> Iterator[Any]:
|
| 27 | + """ |
| 28 | + Iterate through all nodes in the Circular Linked List yielding their data. |
| 29 | + Yields: |
| 30 | + The data of each node in the linked list. |
| 31 | + """ |
19 | 32 | node = self.head
|
20 |
| - while self.head: |
| 33 | + while node: |
21 | 34 | yield node.data
|
22 | 35 | node = node.next
|
23 | 36 | if node == self.head:
|
24 | 37 | break
|
25 | 38 |
|
26 | 39 | def __len__(self) -> int:
|
| 40 | + """ |
| 41 | + Get the length (number of nodes) in the Circular Linked List. |
| 42 | + """ |
27 | 43 | return sum(1 for _ in self)
|
28 | 44 |
|
29 |
| - def __repr__(self): |
| 45 | + def __repr__(self) -> str: |
| 46 | + """ |
| 47 | + Generate a string representation of the Circular Linked List. |
| 48 | + Returns: |
| 49 | + A string of the format "1->2->....->N". |
| 50 | + """ |
30 | 51 | return "->".join(str(item) for item in iter(self))
|
31 | 52 |
|
32 | 53 | def insert_tail(self, data: Any) -> None:
|
| 54 | + """ |
| 55 | + Insert a node with the given data at the end of the Circular Linked List. |
| 56 | + """ |
33 | 57 | self.insert_nth(len(self), data)
|
34 | 58 |
|
35 | 59 | def insert_head(self, data: Any) -> None:
|
| 60 | + """ |
| 61 | + Insert a node with the given data at the beginning of the Circular Linked List. |
| 62 | + """ |
36 | 63 | self.insert_nth(0, data)
|
37 | 64 |
|
38 | 65 | def insert_nth(self, index: int, data: Any) -> None:
|
| 66 | + """ |
| 67 | + Insert the data of the node at the nth pos in the Circular Linked List. |
| 68 | + Args: |
| 69 | + index: The index at which the data should be inserted. |
| 70 | + data: The data to be inserted. |
| 71 | +
|
| 72 | + Raises: |
| 73 | + IndexError: If the index is out of range. |
| 74 | + """ |
39 | 75 | if index < 0 or index > len(self):
|
40 | 76 | raise IndexError("list index out of range.")
|
41 |
| - new_node = Node(data) |
| 77 | + new_node: Node = Node(data) |
42 | 78 | if self.head is None:
|
43 |
| - new_node.next = new_node # first node points itself |
| 79 | + new_node.next = new_node # First node points to itself |
44 | 80 | self.tail = self.head = new_node
|
45 |
| - elif index == 0: # insert at head |
| 81 | + elif index == 0: # Insert at the head |
46 | 82 | new_node.next = self.head
|
| 83 | + assert self.tail is not None # List is not empty, tail exists |
47 | 84 | self.head = self.tail.next = new_node
|
48 | 85 | else:
|
49 |
| - temp = self.head |
| 86 | + temp: Node | None = self.head |
50 | 87 | for _ in range(index - 1):
|
| 88 | + assert temp is not None |
51 | 89 | temp = temp.next
|
| 90 | + assert temp is not None |
52 | 91 | new_node.next = temp.next
|
53 | 92 | temp.next = new_node
|
54 |
| - if index == len(self) - 1: # insert at tail |
| 93 | + if index == len(self) - 1: # Insert at the tail |
55 | 94 | self.tail = new_node
|
56 | 95 |
|
57 |
| - def delete_front(self): |
| 96 | + def delete_front(self) -> Any: |
| 97 | + """ |
| 98 | + Delete and return the data of the node at the front of the Circular Linked List. |
| 99 | + Raises: |
| 100 | + IndexError: If the list is empty. |
| 101 | + """ |
58 | 102 | return self.delete_nth(0)
|
59 | 103 |
|
60 | 104 | def delete_tail(self) -> Any:
|
| 105 | + """ |
| 106 | + Delete and return the data of the node at the end of the Circular Linked List. |
| 107 | + Returns: |
| 108 | + Any: The data of the deleted node. |
| 109 | + Raises: |
| 110 | + IndexError: If the index is out of range. |
| 111 | + """ |
61 | 112 | return self.delete_nth(len(self) - 1)
|
62 | 113 |
|
63 | 114 | def delete_nth(self, index: int = 0) -> Any:
|
| 115 | + """ |
| 116 | + Delete and return the data of the node at the nth pos in Circular Linked List. |
| 117 | + Args: |
| 118 | + index (int): The index of the node to be deleted. Defaults to 0. |
| 119 | + Returns: |
| 120 | + Any: The data of the deleted node. |
| 121 | + Raises: |
| 122 | + IndexError: If the index is out of range. |
| 123 | + """ |
64 | 124 | if not 0 <= index < len(self):
|
65 | 125 | raise IndexError("list index out of range.")
|
66 |
| - delete_node = self.head |
67 |
| - if self.head == self.tail: # just one node |
| 126 | + |
| 127 | + assert self.head is not None and self.tail is not None |
| 128 | + delete_node: Node = self.head |
| 129 | + if self.head == self.tail: # Just one node |
68 | 130 | self.head = self.tail = None
|
69 |
| - elif index == 0: # delete head node |
| 131 | + elif index == 0: # Delete head node |
| 132 | + assert self.tail.next is not None |
70 | 133 | self.tail.next = self.tail.next.next
|
71 | 134 | self.head = self.head.next
|
72 | 135 | else:
|
73 |
| - temp = self.head |
| 136 | + temp: Node | None = self.head |
74 | 137 | for _ in range(index - 1):
|
| 138 | + assert temp is not None |
75 | 139 | temp = temp.next
|
| 140 | + assert temp is not None and temp.next is not None |
76 | 141 | delete_node = temp.next
|
77 | 142 | temp.next = temp.next.next
|
78 |
| - if index == len(self) - 1: # delete at tail |
| 143 | + if index == len(self) - 1: # Delete at tail |
79 | 144 | self.tail = temp
|
80 | 145 | return delete_node.data
|
81 | 146 |
|
82 | 147 | def is_empty(self) -> bool:
|
| 148 | + """ |
| 149 | + Check if the Circular Linked List is empty. |
| 150 | + Returns: |
| 151 | + bool: True if the list is empty, False otherwise. |
| 152 | + """ |
83 | 153 | return len(self) == 0
|
84 | 154 |
|
85 | 155 |
|
86 | 156 | def test_circular_linked_list() -> None:
|
87 | 157 | """
|
| 158 | + Test cases for the CircularLinkedList class. |
88 | 159 | >>> test_circular_linked_list()
|
89 | 160 | """
|
90 | 161 | circular_linked_list = CircularLinkedList()
|
|
0 commit comments