mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-04-20 20:57:35 +00:00
doubly linked list: add dataclass and typing (#12647)
* Node is a dataclass * fix mypy errors * LinkedList is a dataclass * fix mypy errors * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py * Update doubly_linked_list_two.py --------- Co-authored-by: Maxim Smolskiy <mithridatus@mail.ru>
This commit is contained in:
parent
f10a5cbfcc
commit
baab802965
@ -9,25 +9,19 @@
|
|||||||
Delete operation is more efficient
|
Delete operation is more efficient
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Self
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class Node:
|
class Node:
|
||||||
def __init__(self, data: int, previous=None, next_node=None):
|
data: int
|
||||||
self.data = data
|
previous: Self | None = None
|
||||||
self.previous = previous
|
next: Self | None = None
|
||||||
self.next = next_node
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"{self.data}"
|
return f"{self.data}"
|
||||||
|
|
||||||
def get_data(self) -> int:
|
|
||||||
return self.data
|
|
||||||
|
|
||||||
def get_next(self):
|
|
||||||
return self.next
|
|
||||||
|
|
||||||
def get_previous(self):
|
|
||||||
return self.previous
|
|
||||||
|
|
||||||
|
|
||||||
class LinkedListIterator:
|
class LinkedListIterator:
|
||||||
def __init__(self, head):
|
def __init__(self, head):
|
||||||
@ -40,30 +34,30 @@ class LinkedListIterator:
|
|||||||
if not self.current:
|
if not self.current:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
else:
|
else:
|
||||||
value = self.current.get_data()
|
value = self.current.data
|
||||||
self.current = self.current.get_next()
|
self.current = self.current.next
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class LinkedList:
|
class LinkedList:
|
||||||
def __init__(self):
|
head: Node | None = None # First node in list
|
||||||
self.head = None # First node in list
|
tail: Node | None = None # Last node in list
|
||||||
self.tail = None # Last node in list
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
current = self.head
|
current = self.head
|
||||||
nodes = []
|
nodes = []
|
||||||
while current is not None:
|
while current is not None:
|
||||||
nodes.append(current.get_data())
|
nodes.append(current.data)
|
||||||
current = current.get_next()
|
current = current.next
|
||||||
return " ".join(str(node) for node in nodes)
|
return " ".join(str(node) for node in nodes)
|
||||||
|
|
||||||
def __contains__(self, value: int):
|
def __contains__(self, value: int):
|
||||||
current = self.head
|
current = self.head
|
||||||
while current:
|
while current:
|
||||||
if current.get_data() == value:
|
if current.data == value:
|
||||||
return True
|
return True
|
||||||
current = current.get_next()
|
current = current.next
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
@ -71,12 +65,12 @@ class LinkedList:
|
|||||||
|
|
||||||
def get_head_data(self):
|
def get_head_data(self):
|
||||||
if self.head:
|
if self.head:
|
||||||
return self.head.get_data()
|
return self.head.data
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_tail_data(self):
|
def get_tail_data(self):
|
||||||
if self.tail:
|
if self.tail:
|
||||||
return self.tail.get_data()
|
return self.tail.data
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set_head(self, node: Node) -> None:
|
def set_head(self, node: Node) -> None:
|
||||||
@ -103,18 +97,20 @@ class LinkedList:
|
|||||||
node_to_insert.next = node
|
node_to_insert.next = node
|
||||||
node_to_insert.previous = node.previous
|
node_to_insert.previous = node.previous
|
||||||
|
|
||||||
if node.get_previous() is None:
|
if node.previous is None:
|
||||||
self.head = node_to_insert
|
self.head = node_to_insert
|
||||||
else:
|
else:
|
||||||
node.previous.next = node_to_insert
|
node.previous.next = node_to_insert
|
||||||
|
|
||||||
node.previous = node_to_insert
|
node.previous = node_to_insert
|
||||||
|
|
||||||
def insert_after_node(self, node: Node, node_to_insert: Node) -> None:
|
def insert_after_node(self, node: Node | None, node_to_insert: Node) -> None:
|
||||||
|
assert node is not None
|
||||||
|
|
||||||
node_to_insert.previous = node
|
node_to_insert.previous = node
|
||||||
node_to_insert.next = node.next
|
node_to_insert.next = node.next
|
||||||
|
|
||||||
if node.get_next() is None:
|
if node.next is None:
|
||||||
self.tail = node_to_insert
|
self.tail = node_to_insert
|
||||||
else:
|
else:
|
||||||
node.next.previous = node_to_insert
|
node.next.previous = node_to_insert
|
||||||
@ -136,27 +132,27 @@ class LinkedList:
|
|||||||
def get_node(self, item: int) -> Node:
|
def get_node(self, item: int) -> Node:
|
||||||
node = self.head
|
node = self.head
|
||||||
while node:
|
while node:
|
||||||
if node.get_data() == item:
|
if node.data == item:
|
||||||
return node
|
return node
|
||||||
node = node.get_next()
|
node = node.next
|
||||||
raise Exception("Node not found")
|
raise Exception("Node not found")
|
||||||
|
|
||||||
def delete_value(self, value):
|
def delete_value(self, value):
|
||||||
if (node := self.get_node(value)) is not None:
|
if (node := self.get_node(value)) is not None:
|
||||||
if node == self.head:
|
if node == self.head:
|
||||||
self.head = self.head.get_next()
|
self.head = self.head.next
|
||||||
|
|
||||||
if node == self.tail:
|
if node == self.tail:
|
||||||
self.tail = self.tail.get_previous()
|
self.tail = self.tail.previous
|
||||||
|
|
||||||
self.remove_node_pointers(node)
|
self.remove_node_pointers(node)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def remove_node_pointers(node: Node) -> None:
|
def remove_node_pointers(node: Node) -> None:
|
||||||
if node.get_next():
|
if node.next:
|
||||||
node.next.previous = node.previous
|
node.next.previous = node.previous
|
||||||
|
|
||||||
if node.get_previous():
|
if node.previous:
|
||||||
node.previous.next = node.next
|
node.previous.next = node.next
|
||||||
|
|
||||||
node.next = None
|
node.next = None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user