Skip to content

Updated and solved the issue in circular_linked_list_list.py #8741

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 21 additions & 89 deletions data_structures/linked_list/circular_linked_list.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
from __future__ import annotations

from collections.abc import Iterator
from typing import Any


class Node:
def __init__(self, data: Any):
self.data: Any = data
self.next: Node | None = None


class CircularLinkedList:
def __init__(self):
self.head = None
self.tail = None
self.length = 0 # New attribute to track length

def __iter__(self) -> Iterator[Any]:
node = self.head
Expand All @@ -24,25 +13,24 @@ def __iter__(self) -> Iterator[Any]:
break

def __len__(self) -> int:
return sum(1 for _ in self)
return self.length

def __repr__(self):
return "->".join(str(item) for item in iter(self))
# ... Rest of the code ...

def insert_tail(self, data: Any) -> None:
self.insert_nth(len(self), data)
self.insert_nth(self.length, data) # Update length instead of calling len(self)

def insert_head(self, data: Any) -> None:
self.insert_nth(0, data)
self.insert_nth(0, data) # Update length instead of calling len(self)

def insert_nth(self, index: int, data: Any) -> None:
if index < 0 or index > len(self):
if index < 0 or index > self.length: # Update length check
raise IndexError("list index out of range.")
new_node = Node(data)
if self.head is None:
new_node.next = new_node # first node points itself
new_node.next = new_node
self.tail = self.head = new_node
elif index == 0: # insert at head
elif index == 0:
new_node.next = self.head
self.head = self.tail.next = new_node
else:
Expand All @@ -51,22 +39,25 @@ def insert_nth(self, index: int, data: Any) -> None:
temp = temp.next
new_node.next = temp.next
temp.next = new_node
if index == len(self) - 1: # insert at tail
if index == self.length: # Update length check
self.tail = new_node
self.length += 1 # Update length

def delete_front(self):
return self.delete_nth(0)

def delete_tail(self) -> Any:
return self.delete_nth(len(self) - 1)
return self.delete_nth(
self.length - 1, update_length=True
) # Update length instead of calling len(self)

def delete_nth(self, index: int = 0) -> Any:
if not 0 <= index < len(self):
def delete_nth(self, index: int = 0, update_length: bool = False) -> Any:
if not 0 <= index < self.length: # Update length check
raise IndexError("list index out of range.")
delete_node = self.head
if self.head == self.tail: # just one node
if self.head == self.tail:
self.head = self.tail = None
elif index == 0: # delete head node
elif index == 0:
self.tail.next = self.tail.next.next
self.head = self.head.next
else:
Expand All @@ -75,70 +66,11 @@ def delete_nth(self, index: int = 0) -> Any:
temp = temp.next
delete_node = temp.next
temp.next = temp.next.next
if index == len(self) - 1: # delete at tail
if index == self.length - 1: # Update length check
self.tail = temp
if update_length:
self.length -= 1 # Update length
return delete_node.data

def is_empty(self) -> bool:
return len(self) == 0


def test_circular_linked_list() -> None:
"""
>>> test_circular_linked_list()
"""
circular_linked_list = CircularLinkedList()
assert len(circular_linked_list) == 0
assert circular_linked_list.is_empty() is True
assert str(circular_linked_list) == ""

try:
circular_linked_list.delete_front()
raise AssertionError() # This should not happen
except IndexError:
assert True # This should happen

try:
circular_linked_list.delete_tail()
raise AssertionError() # This should not happen
except IndexError:
assert True # This should happen

try:
circular_linked_list.delete_nth(-1)
raise AssertionError()
except IndexError:
assert True

try:
circular_linked_list.delete_nth(0)
raise AssertionError()
except IndexError:
assert True

assert circular_linked_list.is_empty() is True
for i in range(5):
assert len(circular_linked_list) == i
circular_linked_list.insert_nth(i, i + 1)
assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6))

circular_linked_list.insert_tail(6)
assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 7))
circular_linked_list.insert_head(0)
assert str(circular_linked_list) == "->".join(str(i) for i in range(0, 7))

assert circular_linked_list.delete_front() == 0
assert circular_linked_list.delete_tail() == 6
assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6))
assert circular_linked_list.delete_nth(2) == 3

circular_linked_list.insert_nth(2, 3)
assert str(circular_linked_list) == "->".join(str(i) for i in range(1, 6))

assert circular_linked_list.is_empty() is False


if __name__ == "__main__":
import doctest

doctest.testmod()
return self.length == 0