9
9
Delete operation is more efficient
10
10
"""
11
11
12
+ from dataclasses import dataclass
13
+ from typing import Self
12
14
15
+
16
+ @dataclass
13
17
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
18
21
19
22
def __str__ (self ) -> str :
20
23
return f"{ self .data } "
21
24
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
-
31
25
32
26
class LinkedListIterator :
33
27
def __init__ (self , head ):
@@ -40,43 +34,43 @@ def __next__(self):
40
34
if not self .current :
41
35
raise StopIteration
42
36
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
45
39
return value
46
40
47
41
42
+ @dataclass
48
43
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
52
46
53
47
def __str__ (self ):
54
48
current = self .head
55
49
nodes = []
56
50
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
59
53
return " " .join (str (node ) for node in nodes )
60
54
61
55
def __contains__ (self , value : int ):
62
56
current = self .head
63
57
while current :
64
- if current .get_data () == value :
58
+ if current .data == value :
65
59
return True
66
- current = current .get_next ()
60
+ current = current .next
67
61
return False
68
62
69
63
def __iter__ (self ):
70
64
return LinkedListIterator (self .head )
71
65
72
66
def get_head_data (self ):
73
67
if self .head :
74
- return self .head .get_data ()
68
+ return self .head .data
75
69
return None
76
70
77
71
def get_tail_data (self ):
78
72
if self .tail :
79
- return self .tail .get_data ()
73
+ return self .tail .data
80
74
return None
81
75
82
76
def set_head (self , node : Node ) -> None :
@@ -87,8 +81,9 @@ def set_head(self, node: Node) -> None:
87
81
self .insert_before_node (self .head , node )
88
82
89
83
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
92
87
else :
93
88
self .insert_after_node (self .tail , node )
94
89
@@ -103,7 +98,7 @@ def insert_before_node(self, node: Node, node_to_insert: Node) -> None:
103
98
node_to_insert .next = node
104
99
node_to_insert .previous = node .previous
105
100
106
- if node .get_previous () is None :
101
+ if node .previous is None :
107
102
self .head = node_to_insert
108
103
else :
109
104
node .previous .next = node_to_insert
@@ -114,7 +109,7 @@ def insert_after_node(self, node: Node, node_to_insert: Node) -> None:
114
109
node_to_insert .previous = node
115
110
node_to_insert .next = node .next
116
111
117
- if node .get_next () is None :
112
+ if node .next is None :
118
113
self .tail = node_to_insert
119
114
else :
120
115
node .next .previous = node_to_insert
@@ -131,32 +126,32 @@ def insert_at_position(self, position: int, value: int) -> None:
131
126
return
132
127
current_position += 1
133
128
node = node .next
134
- self .insert_after_node ( self . tail , new_node )
129
+ self .set_tail ( new_node )
135
130
136
131
def get_node (self , item : int ) -> Node :
137
132
node = self .head
138
133
while node :
139
- if node .get_data () == item :
134
+ if node .data == item :
140
135
return node
141
- node = node .get_next ()
136
+ node = node .next
142
137
raise Exception ("Node not found" )
143
138
144
139
def delete_value (self , value ):
145
140
if (node := self .get_node (value )) is not None :
146
141
if node == self .head :
147
- self .head = self .head .get_next ()
142
+ self .head = self .head .next
148
143
149
144
if node == self .tail :
150
- self .tail = self .tail .get_previous ()
145
+ self .tail = self .tail .previous
151
146
152
147
self .remove_node_pointers (node )
153
148
154
149
@staticmethod
155
150
def remove_node_pointers (node : Node ) -> None :
156
- if node .get_next () :
151
+ if node .next :
157
152
node .next .previous = node .previous
158
153
159
- if node .get_previous () :
154
+ if node .previous :
160
155
node .previous .next = node .next
161
156
162
157
node .next = None
@@ -241,6 +236,22 @@ def create_linked_list() -> None:
241
236
7
242
237
8
243
238
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'
244
255
"""
245
256
246
257
0 commit comments