Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@
* [Rotate To The Right](data_structures/linked_list/rotate_to_the_right.py)
* [Singly Linked List](data_structures/linked_list/singly_linked_list.py)
* [Skip List](data_structures/linked_list/skip_list.py)
* [Sorted Linked List](data_structures/linked_list/sorted_linked_list.py)
* [Swap Nodes](data_structures/linked_list/swap_nodes.py)
* Queues
* [Circular Queue](data_structures/queues/circular_queue.py)
Expand Down Expand Up @@ -987,6 +988,7 @@
* [Doppler Frequency](physics/doppler_frequency.py)
* [Escape Velocity](physics/escape_velocity.py)
* [Grahams Law](physics/grahams_law.py)
* [Hamiltonian](physics/hamiltonian.py)
* [Horizontal Projectile Motion](physics/horizontal_projectile_motion.py)
* [Hubble Parameter](physics/hubble_parameter.py)
* [Ideal Gas Law](physics/ideal_gas_law.py)
Expand Down
329 changes: 329 additions & 0 deletions data_structures/linked_list/sorted_linked_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
from __future__ import annotations

from collections.abc import Iterator
from dataclasses import dataclass


@dataclass(order=True)
class Node:
"""
A class representing a node in a linked list.

Attributes:
data: The data stored in the node.
next: A reference to the next node in the linked list.

>>> Node(1, Node(2, Node(3)))
Node(data=1, next=Node(data=2, next=Node(data=3, next=None)))
"""

data: int
next: Node | None = None


class SortedLinkedList:
"""This class represents a sorted linked list."""

def __init__(self) -> None:
"""
Create and initialize LinkedList class instance.
>>> linked_list = SortedLinkedList()
>>> linked_list.head is None
True
"""
self.head: Node | None = None
self.tail: Node | None = None

def __iter__(self) -> Iterator[int]:
"""Iterate over the data of the nodes in the linked list.

>>> linked_list = SortedLinkedList()
>>> linked_list.insert(3)
>>> linked_list.insert(1)
>>> linked_list.insert(2)
>>> tuple(linked_list)
(1, 2, 3)
"""
current = self.head
while current:
yield current.data
current = current.next

def __len__(self) -> int:
"""Return the number of nodes in the linked list.

>>> linked_list = SortedLinkedList()
>>> len(linked_list)
0
>>> linked_list.insert(3)
>>> len(linked_list)
1
>>> linked_list.insert(1)
>>> linked_list.insert(2)
>>> len(linked_list)
3
"""
return len(tuple(self))

def __contains__(self, data: int) -> bool:
"""Check if a node with the given data exists in the linked list.

>>> linked_list = SortedLinkedList()
>>> linked_list.insert(3)
>>> 3 in linked_list
True
>>> 1 in linked_list
False
"""
return data in tuple(self)

def insert(self, data: int) -> None:
"""Inserts a node in its sorted position
This function can be rewritten for any data type, but
the comparator here must be changed

Args:
data (int): the data of the linked list

Doctests
>>> linked_list = SortedLinkedList()
>>> linked_list.insert(32)
>>> linked_list.insert(57)
>>> linked_list.insert(45)
>>> tuple(linked_list)
(32, 45, 57)
"""
new_node = Node(data)
if self.head is None:
self.head = new_node
self.tail = new_node
elif new_node < self.head:
new_node.next = self.head
self.head = new_node
else:
temp_node: Node | None = self.head
if temp_node:
while temp_node.next and temp_node.next.data < data:
temp_node = temp_node.next
new_node.next = temp_node.next
temp_node.next = new_node
if new_node.next is None:
self.tail = new_node

def delete(self, data: int) -> bool:
"""This Function deletes first appearance of node with
data from it's sorted position

This function can be re written for any data type but
the comparator her must have to be changed

Args:
data (int): the data of the node that is needed to be deleted

Returns:
bool: status whether the node got deleted or not

Doctests

>>> linkedList=SortedLinkedList()
>>> linkedList.insert(32)
>>> linkedList.insert(57)
>>> linkedList.insert(45)
>>> tuple(linkedList)
(32, 45, 57)
>>> linkedList.delete(45)
True
>>> tuple(linkedList)
(32, 57)
"""
if self.head is None:
return False

if self.head.data == data:
self.head = self.head.next
if self.head is None:
self.tail = None
return True

temp_node: Node | None = self.head
if temp_node:
while temp_node.next:
if temp_node.next.data == data:
temp_node.next = temp_node.next.next
if temp_node.next is None:
self.tail = temp_node
return True
temp_node = temp_node.next

return False

def search(self, data: int) -> bool:
"""This function searches the data given input from user
and return whether the data exists or not

Args:
data (int): Data to be searched

Returns:
bool: flag indicating whether data exists or not

Doctests
>>> linkedList=SortedLinkedList()
>>> linkedList.insert(32)
>>> linkedList.insert(57)
>>> linkedList.insert(45)
>>> tuple(linkedList)
(32, 45, 57)
>>> linkedList.search(45)
True
>>> linkedList.search(90)
False
"""
return data in self

def is_empty(self) -> bool:
"""This function will check whether the list is empty or not

Returns:
bool: flag indicating whether list is empty or not

Doctests

>>> linkedList=SortedLinkedList()
>>> linkedList.is_empty()
True
>>> linkedList.insert(32)
>>> linkedList.insert(57)
>>> linkedList.insert(45)
>>> linkedList.is_empty()
False
"""
return not self

def min_value(self) -> int | None:
"""This function will return minimum value

Returns:
int | None: min value or None if list is empty

Doctests

>>> linkedList=SortedLinkedList()
>>> linkedList.min_value() is None
True
>>> linkedList.insert(32)
>>> linkedList.insert(57)
>>> linkedList.insert(45)
>>> linkedList.min_value()
32
"""
return min(self) if self.head else None

def max_value(self) -> int | None:
"""This function will return maximum value


Returns:
int | None: max value or None if list is empty

Doctests

>>> linkedList=SortedLinkedList()
>>> linkedList.max_value() is None
True
>>> linkedList.insert(32)
>>> linkedList.insert(57)
>>> linkedList.insert(45)
>>> linkedList.max_value()
57
"""
return max(self) if self.head else None

def remove_duplicates(self) -> None:
"""
This Function will remove the duplicates from the list

Doctests

>>> linkedList=SortedLinkedList()
>>> linkedList.insert(32)
>>> linkedList.insert(57)
>>> linkedList.insert(45)
>>> linkedList.insert(45)
>>> tuple(linkedList)
(32, 45, 45, 57)
>>> linkedList.remove_duplicates()
>>> tuple(linkedList)
(32, 45, 57)
"""

temp: Node | None = self.head
while temp and temp.next:
if temp.data == temp.next.data:
temp.next = temp.next.next
else:
temp = temp.next

def merge(self, other_list: SortedLinkedList) -> None:
"""This Function will merge the input list with current list

Args:
other_list (SortedLinkedList): The list to be merged

Doctests

>>> linkedList=SortedLinkedList()
>>> linkedList.insert(32)
>>> linkedList.insert(57)
>>> linkedList.insert(45)
>>> tuple(linkedList)
(32, 45, 57)
>>> linkedList2=SortedLinkedList()
>>> linkedList2.insert(23)
>>> linkedList2.insert(47)
>>> linkedList2.insert(95)
>>> tuple(linkedList2)
(23, 47, 95)
>>> linkedList.merge(linkedList2)
>>> tuple(linkedList)
(23, 32, 45, 47, 57, 95)
"""
if other_list.head is None:
return
elif self.head is None:
self.head = other_list.head
self.tail = other_list.tail
return
else:
temp: Node | None = other_list.head

while temp:
self.insert(temp.data)
temp = temp.next


if __name__ == "__main__":
linked_list = SortedLinkedList()
while True:
print("Enter")
print("1. Insert")
print("2. Display")
print("3. Delete")
print("4. Exit")
choice = input("Enter your choice: ")

if choice == "1":
node_data = int(input("Enter a number: "))
linked_list.insert(node_data)
elif choice == "2":
linked_list.display()
elif choice == "3":
node_data = int(input("Enter the data to delete: "))
if linked_list.delete(node_data):
print(f"Node with data {node_data} deleted successfully")
else:
print(f"Node with data {node_data} not found in the list")
elif choice == "4":
break
else:
print("Wrong input")
Loading