1
1
__all__ = [
2
2
'TreeNode' ,
3
3
'LinkedListNode' ,
4
- 'BinomialTreeNode'
4
+ 'BinomialTreeNode' ,
5
+ 'AdjacencyListGraphNode' ,
6
+ 'AdjacencyMatrixGraphNode' ,
7
+ 'GraphEdge'
5
8
]
6
9
7
10
_check_type = lambda a , t : isinstance (a , t )
@@ -34,7 +37,7 @@ class TreeNode(Node):
34
37
'height' , 'parent' , 'size' ]
35
38
36
39
def __new__ (cls , key , data ):
37
- obj = object .__new__ (cls )
40
+ obj = Node .__new__ (cls )
38
41
obj .data , obj .key = data , key
39
42
obj .left , obj .right , obj .parent , obj .height , obj .size = \
40
43
None , None , None , 0 , 1
@@ -78,7 +81,7 @@ class BinomialTreeNode(TreeNode):
78
81
79
82
def __new__ (cls , key , data ):
80
83
from pydatastructs .linear_data_structures .arrays import DynamicOneDimensionalArray
81
- obj = object .__new__ (cls )
84
+ obj = Node .__new__ (cls )
82
85
obj .data , obj .key = data , key
83
86
obj .children , obj .parent , obj .is_root = (
84
87
DynamicOneDimensionalArray (BinomialTreeNode , 0 ),
@@ -112,7 +115,7 @@ class LinkedListNode(Node):
112
115
Any valid data to be stored in the node.
113
116
"""
114
117
def __new__ (cls , data = None , links = ['next' ], addrs = [None ]):
115
- obj = object .__new__ (cls )
118
+ obj = Node .__new__ (cls )
116
119
obj .data = data
117
120
for link , addr in zip (links , addrs ):
118
121
obj .__setattr__ (link , addr )
@@ -121,3 +124,102 @@ def __new__(cls, data=None, links=['next'], addrs=[None]):
121
124
122
125
def __str__ (self ):
123
126
return str (self .data )
127
+
128
+ class GraphNode (Node ):
129
+ """
130
+ Abastract class for graph nodes/vertices.
131
+ """
132
+ def __str__ (self ):
133
+ return str ((self .name , self .data ))
134
+
135
+ class AdjacencyListGraphNode (GraphNode ):
136
+ """
137
+ Represents nodes for adjacency list implementation
138
+ of graphs.
139
+
140
+ Parameters
141
+ ==========
142
+
143
+ name: str
144
+ The name of the node by which it is identified
145
+ in the graph. Must be unique.
146
+ data
147
+ The data to be stored at each graph node.
148
+ adjacency_list: iterator
149
+ Any valid iterator to initialize the adjacent
150
+ nodes of the current node.
151
+ Optional, by default, None
152
+ """
153
+ def __new__ (cls , name , data , adjacency_list = None ):
154
+ obj = GraphNode .__new__ (cls )
155
+ obj .name , obj .data = name , data
156
+ if adjacency_list is not None :
157
+ for node in adjacency_list :
158
+ obj .__setattr__ (node .name , node )
159
+ obj .adjacent = set (adjacency_list ) if adjacency_list is not None \
160
+ else set ()
161
+ return obj
162
+
163
+ def add_adjacent_node (self , name , data ):
164
+ """
165
+ Adds adjacent node to the current node's
166
+ adjacency list with given name and data.
167
+ """
168
+ if hasattr (self , name ):
169
+ getattr (self , name ).data = data
170
+ else :
171
+ new_node = AdjacencyListGraphNode (name , data )
172
+ self .__setattr__ (new_node .name , new_node )
173
+ self .adjacent .add (new_node .name )
174
+
175
+ def remove_adjacent_node (self , name ):
176
+ """
177
+ Removes node with given name from
178
+ adjacency list.
179
+ """
180
+ if not hasattr (self , name ):
181
+ raise ValueError ("%s is not adjacent to %s" % (name , self .name ))
182
+ self .adjacent .remove (name )
183
+ delattr (self , name )
184
+
185
+ class AdjacencyMatrixGraphNode (GraphNode ):
186
+ """
187
+ Represents nodes for adjacency matrix implementation
188
+ of graphs.
189
+
190
+ Parameters
191
+ ==========
192
+
193
+ name: str
194
+ The name of the node by which it is identified
195
+ in the graph. Must be unique.
196
+ data
197
+ The data to be stored at each graph node.
198
+ """
199
+ __slots__ = ['name' , 'data' ]
200
+
201
+ def __new__ (cls , name , data ):
202
+ obj = GraphNode .__new__ (cls )
203
+ obj .name , obj .data = name , data
204
+ return obj
205
+
206
+ class GraphEdge (object ):
207
+ """
208
+ Represents the concept of edges in graphs.
209
+
210
+ Parameters
211
+ ==========
212
+
213
+ node1: GraphNode or it's child classes
214
+ The source node of the edge.
215
+ node2: GraphNode or it's child classes
216
+ The target node of the edge.
217
+ """
218
+ def __new__ (cls , node1 , node2 , value = None ):
219
+ obj = object .__new__ (cls )
220
+ obj .source , obj .target = node1 , node2
221
+ obj .value = value
222
+ return obj
223
+
224
+ def __str__ (self ):
225
+ return str ((self .source .name , self .target .name ))
0 commit comments