Skip to content

Commit 22f8647

Browse files
committed
2 parents d0979d3 + def94b6 commit 22f8647

File tree

3 files changed

+128
-29
lines changed

3 files changed

+128
-29
lines changed

DIRECTORY.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,8 @@
541541
* [Basic Maths](maths/basic_maths.py)
542542
* [Binary Exp Mod](maths/binary_exp_mod.py)
543543
* [Binary Exponentiation](maths/binary_exponentiation.py)
544-
* [Binary Exponentiation 2](maths/binary_exponentiation_2.py)
545544
* [Binary Exponentiation 3](maths/binary_exponentiation_3.py)
545+
* [Binary Multiplication](maths/binary_multiplication.py)
546546
* [Binomial Coefficient](maths/binomial_coefficient.py)
547547
* [Binomial Distribution](maths/binomial_distribution.py)
548548
* [Bisection](maths/bisection.py)
@@ -557,8 +557,7 @@
557557
* [Decimal Isolate](maths/decimal_isolate.py)
558558
* [Decimal To Fraction](maths/decimal_to_fraction.py)
559559
* [Dodecahedron](maths/dodecahedron.py)
560-
* [Double Factorial Iterative](maths/double_factorial_iterative.py)
561-
* [Double Factorial Recursive](maths/double_factorial_recursive.py)
560+
* [Double Factorial](maths/double_factorial.py)
562561
* [Dual Number Automatic Differentiation](maths/dual_number_automatic_differentiation.py)
563562
* [Entropy](maths/entropy.py)
564563
* [Euclidean Distance](maths/euclidean_distance.py)

data_structures/linked_list/circular_linked_list.py

Lines changed: 88 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,85 +6,156 @@
66

77
class Node:
88
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+
"""
914
self.data: Any = data
10-
self.next: Node | None = None
15+
self.next: Node | None = None # Reference to the next node
1116

1217

1318
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)
1725

1826
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+
"""
1932
node = self.head
20-
while self.head:
33+
while node:
2134
yield node.data
2235
node = node.next
2336
if node == self.head:
2437
break
2538

2639
def __len__(self) -> int:
40+
"""
41+
Get the length (number of nodes) in the Circular Linked List.
42+
"""
2743
return sum(1 for _ in self)
2844

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+
"""
3051
return "->".join(str(item) for item in iter(self))
3152

3253
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+
"""
3357
self.insert_nth(len(self), data)
3458

3559
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+
"""
3663
self.insert_nth(0, data)
3764

3865
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+
"""
3975
if index < 0 or index > len(self):
4076
raise IndexError("list index out of range.")
41-
new_node = Node(data)
77+
new_node: Node = Node(data)
4278
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
4480
self.tail = self.head = new_node
45-
elif index == 0: # insert at head
81+
elif index == 0: # Insert at the head
4682
new_node.next = self.head
83+
assert self.tail is not None # List is not empty, tail exists
4784
self.head = self.tail.next = new_node
4885
else:
49-
temp = self.head
86+
temp: Node | None = self.head
5087
for _ in range(index - 1):
88+
assert temp is not None
5189
temp = temp.next
90+
assert temp is not None
5291
new_node.next = temp.next
5392
temp.next = new_node
54-
if index == len(self) - 1: # insert at tail
93+
if index == len(self) - 1: # Insert at the tail
5594
self.tail = new_node
5695

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+
"""
58102
return self.delete_nth(0)
59103

60104
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+
"""
61112
return self.delete_nth(len(self) - 1)
62113

63114
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+
"""
64124
if not 0 <= index < len(self):
65125
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
68130
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
70133
self.tail.next = self.tail.next.next
71134
self.head = self.head.next
72135
else:
73-
temp = self.head
136+
temp: Node | None = self.head
74137
for _ in range(index - 1):
138+
assert temp is not None
75139
temp = temp.next
140+
assert temp is not None and temp.next is not None
76141
delete_node = temp.next
77142
temp.next = temp.next.next
78-
if index == len(self) - 1: # delete at tail
143+
if index == len(self) - 1: # Delete at tail
79144
self.tail = temp
80145
return delete_node.data
81146

82147
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+
"""
83153
return len(self) == 0
84154

85155

86156
def test_circular_linked_list() -> None:
87157
"""
158+
Test cases for the CircularLinkedList class.
88159
>>> test_circular_linked_list()
89160
"""
90161
circular_linked_list = CircularLinkedList()

data_structures/linked_list/swap_nodes.py

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,56 @@
22

33

44
class Node:
5-
def __init__(self, data: Any):
5+
def __init__(self, data: Any) -> None:
6+
"""
7+
Initialize a new Node with the given data.
8+
9+
Args:
10+
data: The data to be stored in the node.
11+
12+
"""
613
self.data = data
7-
self.next = None
14+
self.next: Node | None = None # Reference to the next node
815

916

1017
class LinkedList:
11-
def __init__(self):
12-
self.head = None
18+
def __init__(self) -> None:
19+
"""
20+
Initialize an empty Linked List.
21+
"""
22+
self.head: Node | None = None # Reference to the head (first node)
1323

1424
def print_list(self):
25+
"""
26+
Print the elements of the Linked List in order.
27+
"""
1528
temp = self.head
1629
while temp is not None:
1730
print(temp.data, end=" ")
1831
temp = temp.next
1932
print()
2033

21-
# adding nodes
22-
def push(self, new_data: Any):
34+
def push(self, new_data: Any) -> None:
35+
"""
36+
Add a new node with the given data to the beginning of the Linked List.
37+
Args:
38+
new_data (Any): The data to be added to the new node.
39+
"""
2340
new_node = Node(new_data)
2441
new_node.next = self.head
2542
self.head = new_node
2643

27-
# swapping nodes
28-
def swap_nodes(self, node_data_1, node_data_2):
44+
def swap_nodes(self, node_data_1, node_data_2) -> None:
45+
"""
46+
Swap the positions of two nodes in the Linked List based on their data values.
47+
Args:
48+
node_data_1: Data value of the first node to be swapped.
49+
node_data_2: Data value of the second node to be swapped.
50+
51+
52+
Note:
53+
If either of the specified data values isn't found then, no swapping occurs.
54+
"""
2955
if node_data_1 == node_data_2:
3056
return
3157
else:
@@ -40,6 +66,7 @@ def swap_nodes(self, node_data_1, node_data_2):
4066
if node_1 is None or node_2 is None:
4167
return
4268

69+
# Swap the data values of the two nodes
4370
node_1.data, node_2.data = node_2.data, node_1.data
4471

4572

@@ -48,8 +75,10 @@ def swap_nodes(self, node_data_1, node_data_2):
4875
for i in range(5, 0, -1):
4976
ll.push(i)
5077

78+
print("Original Linked List:")
5179
ll.print_list()
5280

5381
ll.swap_nodes(1, 4)
54-
print("After swapping")
82+
print("After swapping the nodes whose data is 1 and 4:")
83+
5584
ll.print_list()

0 commit comments

Comments
 (0)