Skip to content

Commit 9497d0a

Browse files
authored
Merge branch 'TheAlgorithms:master' into master
2 parents b6b8288 + 0c8cf8e commit 9497d0a

File tree

2 files changed

+82
-38
lines changed

2 files changed

+82
-38
lines changed

data_structures/linked_list/doubly_linked_list_two.py

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,19 @@
99
Delete operation is more efficient
1010
"""
1111

12+
from dataclasses import dataclass
13+
from typing import Self
1214

15+
16+
@dataclass
1317
class Node:
14-
def __init__(self, data: int, previous=None, next_node=None):
15-
self.data = data
16-
self.previous = previous
17-
self.next = next_node
18+
data: int
19+
previous: Self | None = None
20+
next: Self | None = None
1821

1922
def __str__(self) -> str:
2023
return f"{self.data}"
2124

22-
def get_data(self) -> int:
23-
return self.data
24-
25-
def get_next(self):
26-
return self.next
27-
28-
def get_previous(self):
29-
return self.previous
30-
3125

3226
class LinkedListIterator:
3327
def __init__(self, head):
@@ -40,43 +34,43 @@ def __next__(self):
4034
if not self.current:
4135
raise StopIteration
4236
else:
43-
value = self.current.get_data()
44-
self.current = self.current.get_next()
37+
value = self.current.data
38+
self.current = self.current.next
4539
return value
4640

4741

42+
@dataclass
4843
class LinkedList:
49-
def __init__(self):
50-
self.head = None # First node in list
51-
self.tail = None # Last node in list
44+
head: Node | None = None # First node in list
45+
tail: Node | None = None # Last node in list
5246

5347
def __str__(self):
5448
current = self.head
5549
nodes = []
5650
while current is not None:
57-
nodes.append(current.get_data())
58-
current = current.get_next()
51+
nodes.append(current.data)
52+
current = current.next
5953
return " ".join(str(node) for node in nodes)
6054

6155
def __contains__(self, value: int):
6256
current = self.head
6357
while current:
64-
if current.get_data() == value:
58+
if current.data == value:
6559
return True
66-
current = current.get_next()
60+
current = current.next
6761
return False
6862

6963
def __iter__(self):
7064
return LinkedListIterator(self.head)
7165

7266
def get_head_data(self):
7367
if self.head:
74-
return self.head.get_data()
68+
return self.head.data
7569
return None
7670

7771
def get_tail_data(self):
7872
if self.tail:
79-
return self.tail.get_data()
73+
return self.tail.data
8074
return None
8175

8276
def set_head(self, node: Node) -> None:
@@ -87,8 +81,9 @@ def set_head(self, node: Node) -> None:
8781
self.insert_before_node(self.head, node)
8882

8983
def set_tail(self, node: Node) -> None:
90-
if self.head is None:
91-
self.set_head(node)
84+
if self.tail is None:
85+
self.head = node
86+
self.tail = node
9287
else:
9388
self.insert_after_node(self.tail, node)
9489

@@ -103,7 +98,7 @@ def insert_before_node(self, node: Node, node_to_insert: Node) -> None:
10398
node_to_insert.next = node
10499
node_to_insert.previous = node.previous
105100

106-
if node.get_previous() is None:
101+
if node.previous is None:
107102
self.head = node_to_insert
108103
else:
109104
node.previous.next = node_to_insert
@@ -114,7 +109,7 @@ def insert_after_node(self, node: Node, node_to_insert: Node) -> None:
114109
node_to_insert.previous = node
115110
node_to_insert.next = node.next
116111

117-
if node.get_next() is None:
112+
if node.next is None:
118113
self.tail = node_to_insert
119114
else:
120115
node.next.previous = node_to_insert
@@ -131,32 +126,32 @@ def insert_at_position(self, position: int, value: int) -> None:
131126
return
132127
current_position += 1
133128
node = node.next
134-
self.insert_after_node(self.tail, new_node)
129+
self.set_tail(new_node)
135130

136131
def get_node(self, item: int) -> Node:
137132
node = self.head
138133
while node:
139-
if node.get_data() == item:
134+
if node.data == item:
140135
return node
141-
node = node.get_next()
136+
node = node.next
142137
raise Exception("Node not found")
143138

144139
def delete_value(self, value):
145140
if (node := self.get_node(value)) is not None:
146141
if node == self.head:
147-
self.head = self.head.get_next()
142+
self.head = self.head.next
148143

149144
if node == self.tail:
150-
self.tail = self.tail.get_previous()
145+
self.tail = self.tail.previous
151146

152147
self.remove_node_pointers(node)
153148

154149
@staticmethod
155150
def remove_node_pointers(node: Node) -> None:
156-
if node.get_next():
151+
if node.next:
157152
node.next.previous = node.previous
158153

159-
if node.get_previous():
154+
if node.previous:
160155
node.previous.next = node.next
161156

162157
node.next = None
@@ -241,6 +236,22 @@ def create_linked_list() -> None:
241236
7
242237
8
243238
9
239+
>>> linked_list = LinkedList()
240+
>>> linked_list.insert_at_position(position=1, value=10)
241+
>>> str(linked_list)
242+
'10'
243+
>>> linked_list.insert_at_position(position=2, value=20)
244+
>>> str(linked_list)
245+
'10 20'
246+
>>> linked_list.insert_at_position(position=1, value=30)
247+
>>> str(linked_list)
248+
'30 10 20'
249+
>>> linked_list.insert_at_position(position=3, value=40)
250+
>>> str(linked_list)
251+
'30 10 40 20'
252+
>>> linked_list.insert_at_position(position=5, value=50)
253+
>>> str(linked_list)
254+
'30 10 40 20 50'
244255
"""
245256

246257

data_structures/stacks/prefix_evaluation.py

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""
2-
Python3 program to evaluate a prefix expression.
2+
Program to evaluate a prefix expression.
3+
https://en.wikipedia.org/wiki/Polish_notation
34
"""
45

5-
calc = {
6+
operators = {
67
"+": lambda x, y: x + y,
78
"-": lambda x, y: x - y,
89
"*": lambda x, y: x * y,
@@ -31,6 +32,10 @@ def evaluate(expression):
3132
21
3233
>>> evaluate("/ * 10 2 + 4 1 ")
3334
4.0
35+
>>> evaluate("2")
36+
2
37+
>>> evaluate("+ * 2 3 / 8 4")
38+
8.0
3439
"""
3540
stack = []
3641

@@ -45,11 +50,39 @@ def evaluate(expression):
4550
# push the result onto the stack again
4651
o1 = stack.pop()
4752
o2 = stack.pop()
48-
stack.append(calc[c](o1, o2))
53+
stack.append(operators[c](o1, o2))
4954

5055
return stack.pop()
5156

5257

58+
def evaluate_recursive(expression: list[str]):
59+
"""
60+
Alternative recursive implementation
61+
62+
>>> evaluate_recursive(['2'])
63+
2
64+
>>> expression = ['+', '*', '2', '3', '/', '8', '4']
65+
>>> evaluate_recursive(expression)
66+
8.0
67+
>>> expression
68+
[]
69+
>>> evaluate_recursive(['+', '9', '*', '2', '6'])
70+
21
71+
>>> evaluate_recursive(['/', '*', '10', '2', '+', '4', '1'])
72+
4.0
73+
"""
74+
75+
op = expression.pop(0)
76+
if is_operand(op):
77+
return int(op)
78+
79+
operation = operators[op]
80+
81+
a = evaluate_recursive(expression)
82+
b = evaluate_recursive(expression)
83+
return operation(a, b)
84+
85+
5386
# Driver code
5487
if __name__ == "__main__":
5588
test_expression = "+ 9 * 2 6"

0 commit comments

Comments
 (0)