Skip to content

Commit d679932

Browse files
committed
Add data_structures/linked_list/sorted_linked_list.py
1 parent 37d41a7 commit d679932

1 file changed

Lines changed: 329 additions & 0 deletions

File tree

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
from __future__ import annotations
2+
3+
from collections.abc import Iterator
4+
from dataclasses import dataclass
5+
6+
7+
@dataclass(order=True)
8+
class Node:
9+
"""
10+
A class representing a node in a linked list.
11+
12+
Attributes:
13+
data: The data stored in the node.
14+
next: A reference to the next node in the linked list.
15+
16+
>>> Node(1, Node(2, Node(3)))
17+
Node(data=1, next=Node(data=2, next=Node(data=3, next=None)))
18+
"""
19+
20+
data: int
21+
next: Node | None = None
22+
23+
24+
class SortedLinkedList:
25+
"""This class represents a sorted linked list."""
26+
27+
def __init__(self) -> None:
28+
"""
29+
Create and initialize LinkedList class instance.
30+
>>> linked_list = SortedLinkedList()
31+
>>> linked_list.head is None
32+
True
33+
"""
34+
self.head: Node | None = None
35+
self.tail: Node | None = None
36+
37+
def __iter__(self) -> Iterator[int]:
38+
"""Iterate over the data of the nodes in the linked list.
39+
40+
>>> linked_list = SortedLinkedList()
41+
>>> linked_list.insert(3)
42+
>>> linked_list.insert(1)
43+
>>> linked_list.insert(2)
44+
>>> tuple(linked_list)
45+
(1, 2, 3)
46+
"""
47+
current = self.head
48+
while current:
49+
yield current.data
50+
current = current.next
51+
52+
def __len__(self) -> int:
53+
"""Return the number of nodes in the linked list.
54+
55+
>>> linked_list = SortedLinkedList()
56+
>>> len(linked_list)
57+
0
58+
>>> linked_list.insert(3)
59+
>>> len(linked_list)
60+
1
61+
>>> linked_list.insert(1)
62+
>>> linked_list.insert(2)
63+
>>> len(linked_list)
64+
3
65+
"""
66+
return len(tuple(self))
67+
68+
def __contains__(self, data: int) -> bool:
69+
"""Check if a node with the given data exists in the linked list.
70+
71+
>>> linked_list = SortedLinkedList()
72+
>>> linked_list.insert(3)
73+
>>> 3 in linked_list
74+
True
75+
>>> 1 in linked_list
76+
False
77+
"""
78+
return data in tuple(self)
79+
80+
def insert(self, data: int) -> None:
81+
"""Inserts a node in its sorted position
82+
This function can be rewritten for any data type, but
83+
the comparator here must be changed
84+
85+
Args:
86+
data (int): the data of the linked list
87+
88+
Doctests
89+
>>> linked_list = SortedLinkedList()
90+
>>> linked_list.insert(32)
91+
>>> linked_list.insert(57)
92+
>>> linked_list.insert(45)
93+
>>> tuple(linked_list)
94+
(32, 45, 57)
95+
"""
96+
new_node = Node(data)
97+
if self.head is None:
98+
self.head = new_node
99+
self.tail = new_node
100+
elif new_node < self.head:
101+
new_node.next = self.head
102+
self.head = new_node
103+
else:
104+
temp_node: Node | None = self.head
105+
if temp_node:
106+
while temp_node.next and temp_node.next.data < data:
107+
temp_node = temp_node.next
108+
new_node.next = temp_node.next
109+
temp_node.next = new_node
110+
if new_node.next is None:
111+
self.tail = new_node
112+
113+
def delete(self, data: int) -> bool:
114+
"""This Function deletes first appearance of node with
115+
data from it's sorted position
116+
117+
This function can be re written for any data type but
118+
the comparator her must have to be changed
119+
120+
Args:
121+
data (int): the data of the node that is needed to be deleted
122+
123+
Returns:
124+
bool: status whether the node got deleted or not
125+
126+
Doctests
127+
128+
>>> linkedList=SortedLinkedList()
129+
>>> linkedList.insert(32)
130+
>>> linkedList.insert(57)
131+
>>> linkedList.insert(45)
132+
>>> tuple(linkedList)
133+
(32, 45, 57)
134+
>>> linkedList.delete(45)
135+
True
136+
>>> tuple(linkedList)
137+
(32, 57)
138+
"""
139+
if self.head is None:
140+
return False
141+
142+
if self.head.data == data:
143+
self.head = self.head.next
144+
if self.head is None:
145+
self.tail = None
146+
return True
147+
148+
temp_node: Node | None = self.head
149+
if temp_node:
150+
while temp_node.next:
151+
if temp_node.next.data == data:
152+
temp_node.next = temp_node.next.next
153+
if temp_node.next is None:
154+
self.tail = temp_node
155+
return True
156+
temp_node = temp_node.next
157+
158+
return False
159+
160+
def search(self, data: int) -> bool:
161+
"""This function searches the data given input from user
162+
and return whether the data exists or not
163+
164+
Args:
165+
data (int): Data to be searched
166+
167+
Returns:
168+
bool: flag indicating whether data exists or not
169+
170+
Doctests
171+
>>> linkedList=SortedLinkedList()
172+
>>> linkedList.insert(32)
173+
>>> linkedList.insert(57)
174+
>>> linkedList.insert(45)
175+
>>> tuple(linkedList)
176+
(32, 45, 57)
177+
>>> linkedList.search(45)
178+
True
179+
>>> linkedList.search(90)
180+
False
181+
"""
182+
return data in self
183+
184+
def is_empty(self) -> bool:
185+
"""This function will check whether the list is empty or not
186+
187+
Returns:
188+
bool: flag indicating whether list is empty or not
189+
190+
Doctests
191+
192+
>>> linkedList=SortedLinkedList()
193+
>>> linkedList.is_empty()
194+
True
195+
>>> linkedList.insert(32)
196+
>>> linkedList.insert(57)
197+
>>> linkedList.insert(45)
198+
>>> linkedList.is_empty()
199+
False
200+
"""
201+
return not self
202+
203+
def min_value(self) -> int | None:
204+
"""This function will return minimum value
205+
206+
Returns:
207+
int | None: min value or None if list is empty
208+
209+
Doctests
210+
211+
>>> linkedList=SortedLinkedList()
212+
>>> linkedList.min_value() is None
213+
True
214+
>>> linkedList.insert(32)
215+
>>> linkedList.insert(57)
216+
>>> linkedList.insert(45)
217+
>>> linkedList.min_value()
218+
32
219+
"""
220+
return min(self) if self.head else None
221+
222+
def max_value(self) -> int | None:
223+
"""This function will return maximum value
224+
225+
226+
Returns:
227+
int | None: max value or None if list is empty
228+
229+
Doctests
230+
231+
>>> linkedList=SortedLinkedList()
232+
>>> linkedList.max_value() is None
233+
True
234+
>>> linkedList.insert(32)
235+
>>> linkedList.insert(57)
236+
>>> linkedList.insert(45)
237+
>>> linkedList.max_value()
238+
57
239+
"""
240+
return max(self) if self.head else None
241+
242+
def remove_duplicates(self) -> None:
243+
"""
244+
This Function will remove the duplicates from the list
245+
246+
Doctests
247+
248+
>>> linkedList=SortedLinkedList()
249+
>>> linkedList.insert(32)
250+
>>> linkedList.insert(57)
251+
>>> linkedList.insert(45)
252+
>>> linkedList.insert(45)
253+
>>> tuple(linkedList)
254+
(32, 45, 45, 57)
255+
>>> linkedList.remove_duplicates()
256+
>>> tuple(linkedList)
257+
(32, 45, 57)
258+
"""
259+
260+
temp: Node | None = self.head
261+
while temp and temp.next:
262+
if temp.data == temp.next.data:
263+
temp.next = temp.next.next
264+
else:
265+
temp = temp.next
266+
267+
def merge(self, other_list: SortedLinkedList) -> None:
268+
"""This Function will merge the input list with current list
269+
270+
Args:
271+
other_list (SortedLinkedList): The list to be merged
272+
273+
Doctests
274+
275+
>>> linkedList=SortedLinkedList()
276+
>>> linkedList.insert(32)
277+
>>> linkedList.insert(57)
278+
>>> linkedList.insert(45)
279+
>>> tuple(linkedList)
280+
(32, 45, 57)
281+
>>> linkedList2=SortedLinkedList()
282+
>>> linkedList2.insert(23)
283+
>>> linkedList2.insert(47)
284+
>>> linkedList2.insert(95)
285+
>>> tuple(linkedList2)
286+
(23, 47, 95)
287+
>>> linkedList.merge(linkedList2)
288+
>>> tuple(linkedList)
289+
(23, 32, 45, 47, 57, 95)
290+
"""
291+
if other_list.head is None:
292+
return
293+
elif self.head is None:
294+
self.head = other_list.head
295+
self.tail = other_list.tail
296+
return
297+
else:
298+
temp: Node | None = other_list.head
299+
300+
while temp:
301+
self.insert(temp.data)
302+
temp = temp.next
303+
304+
305+
if __name__ == "__main__":
306+
linked_list = SortedLinkedList()
307+
while True:
308+
print("Enter")
309+
print("1. Insert")
310+
print("2. Display")
311+
print("3. Delete")
312+
print("4. Exit")
313+
choice = input("Enter your choice: ")
314+
315+
if choice == "1":
316+
node_data = int(input("Enter a number: "))
317+
linked_list.insert(node_data)
318+
elif choice == "2":
319+
linked_list.display()
320+
elif choice == "3":
321+
node_data = int(input("Enter the data to delete: "))
322+
if linked_list.delete(node_data):
323+
print(f"Node with data {node_data} deleted successfully")
324+
else:
325+
print(f"Node with data {node_data} not found in the list")
326+
elif choice == "4":
327+
break
328+
else:
329+
print("Wrong input")

0 commit comments

Comments
 (0)