Package coinor :: Package blimpy :: Module LinkedList'
[hide private]
[frames] | no frames]

Source Code for Module coinor.blimpy.LinkedList'

  1  ''' 
  2  Lists Module 
  3  A basic linked list implementation conforming to the Python list API. 
  4  It can be used as a drop-in replacement for the built-in list class. 
  5  Created on Jan 29, 2012 
  6  ''' 
  7   
  8  __version__    = '1.1.0' 
  9  __author__     = 'Ted Ralphs, Aykut Bulut (ted@lehigh.edu, ayb211@lehigh.edu)' 
 10  __license__    = 'BSD' 
 11  __maintainer__ = 'Aykut Bulut' 
 12  __email__      = 'ayb211@lehigh.edu' 
 13  __url__        = None 
 14  __title__      = 'Linked list data structure' 
 15   
 16  from copy import deepcopy 
 17   
18 -class Node(object):
19 ''' Basic data type that LinkedList will contain 20 pre: data that node will contain 21 post: Node type object 22 '''
23 - def __init__(self, initdata, nextNode = None):
24 '''constructor of Node class 25 pre: Node class object (self), initial data (initdata)''' 26 self.data = initdata 27 self.nextNode = nextNode
28
29 - def getData(self):
30 ''' class method that returns to data 31 pre: self 32 post: data of the Node''' 33 return self.data
34
35 - def getNext(self):
36 return self.nextNode
37
38 - def setData(self, newdata):
39 ''' class method that sets data 40 pre: self, new data''' 41 self.data = newdata
42
43 - def setNext(self, newnext):
44 ''' class method that changes the next Node 45 pre: self, new next''' 46 self.nextNode = newnext
47
48 - def __repr__(self):
49 return 'Node instance, data:%s, nextNode:%s' %(self.getData(), self.getNext())
50
51 - def __str__(self):
52 return str(self.data)
53 54
55 -class LinkedList(object):
56 '''implementation of link list data structure. 57 The behavior is designed to be the same as a Python list. 58 For efficiency when using the list as a stack, the list is stored 59 such that the last item in the list is the head node. Thus, the 60 append, push, pop, and most other methods are efficient, but 61 forward iteration is not. Reverse iteration is efficient, however, 62 pre: Node is the head node of a linked list and length is the length of 63 that list 64 post: creates a LinkedList type object 65 ''' 66
67 - def __init__(self, Node=None, length = 0):
68 ''' constructor method of the class 69 pre: self''' 70 self.head = Node 71 self.length = length
72
73 - def __contains__(self, item):
74 ''' sequential search method 75 pre: self, item to be searched 76 post: True if list contains the item, False otherwise''' 77 current = self.head 78 while current != None: 79 if current.getData() == item: 80 return True 81 else: 82 current = current.getNext() 83 return False
84
85 - def remove(self, item):
86 ''' class method that removes the first occurrence of the given item 87 if there is one 88 pre: self, item ''' 89 current = self.head 90 previous = None 91 found = False 92 while not found and current != None: 93 if current.getData() == item: 94 found = True 95 else: 96 previous = current 97 current = current.getNext() 98 99 if not found: 100 return False 101 elif previous == None: 102 self.head = current.getNext() 103 else: 104 previous.setNext(current.getNext()) 105 self.length -= 1 106 return True
107
108 - def __delitem__(self, position):
109 if self.pop(position) == None: 110 raise KeyError, "Index out of bounds"
111
112 - def insert(self, position, item):
113 ''' class method that inserts item to the given position 114 pre: self, position, item 115 position should not be greater than length of the list''' 116 previous = None 117 current = self.head 118 for i in range(self.length - position): 119 previous = current 120 current = current.getNext() 121 tmp = Node(item, current) 122 if previous == None: 123 self.head = tmp 124 else: 125 previous.setNext(tmp) 126 self.length += 1
127
128 - def peek(self, index = None):
129 ''' class method that retrieves, but does not remove, 130 the head (first element) of this list 131 pre: self 132 post: the data of the head of the list or None if the list is empty''' 133 if self.head == None: 134 return None 135 elif index == None: 136 return self.head.getData() 137 else: 138 return self[index]
139
140 - def pop(self, index = None):
141 ''' class method that removes the item at the given position 142 in the list, and returns it. If no index is specified 143 removes and returns the last item in the list 144 pre: self, position (optional), position should be less than length 145 of the list, list should not be empty 146 post: return the item at given index or last item if not specified''' 147 if (index is not None and 148 (index > self.length -1 or index < 0)): 149 return None 150 previous = None 151 current = self.head 152 if index == None: 153 current = self.head 154 self.head = self.head.getNext() 155 else: 156 for i in range(self.length - index - 1): 157 previous = current 158 current = current.getNext() 159 if previous == None: 160 self.head = current.getNext() 161 else: 162 previous.setNext(current.getNext()) 163 self.length -= 1 164 return current.data
165
166 - def __len__(self):
167 ''' class method that returns the number of items in the list 168 pre: self 169 post: returns number of items in the list''' 170 return self.length
171
172 - def append(self, item):
173 ''' class method that appends the given item at the end of the list 174 pre: self, item''' 175 current = self.head 176 self.head = Node(item) 177 self.head.nextNode = current 178 self.length += 1
179
180 - def extend(self, otherLinkedList):
181 ''' class method that extends the list by adding otherLinkedList at the 182 end of the self 183 pre: self, otherLinkedList''' 184 #if self.head==None: 185 # self.head = otherLinkedList.head 186 # return 187 #if otherLinkedList.head==None: 188 # return 189 for item in otherLinkedList: 190 self.append(item)
191
192 - def index(self, item):
193 ''' class method that returns the index of the first occurance of 194 item, returns None if there is no any item. 195 pre: self, item 196 post: item index or None''' 197 current = self.head 198 for index in range(self.length, 0 , -1): 199 if current == None: 200 break 201 if current.getData() == item: 202 return index 203 current = current.getNext() 204 return None
205
206 - def count(self, item):
207 ''' class method that counts the number of occurances of item 208 in the list 209 pre: self, item 210 post: number of occurances of item in the list''' 211 count = 0 212 current = self.head 213 while current != None: 214 if current.getData() == item: 215 count += 1 216 return count
217
218 - def __getitem__ (self, index):
219 ''' replace built-in class method that returns the item for the given 220 index 221 pre: self, index, index should be less than length of list, list 222 should not be empty 223 post: return item for the given index''' 224 if isinstance(index, slice): 225 if index.start == None or index.start < 0: 226 start = 0 227 else: 228 start = index.start 229 if index.stop == None or index.stop > self.length: 230 stop = self.length 231 else: 232 stop = index.stop 233 current = self.head 234 for i in range(self.length - stop): 235 current = current.getNext() 236 newHead = Node(deepcopy(current.data)) 237 previous = newHead 238 for i in range(stop - start -1): 239 if current.getNext() == None: 240 break 241 current = current.getNext() 242 previous.setNext(Node(deepcopy(current.data))) 243 previous = previous.getNext() 244 return LinkedList(newHead, stop - start) 245 else: 246 current = self.head 247 if index < 0: 248 if -index > self.length: 249 raise IndexError 250 return self[self.length+index] 251 else: 252 i = self.length - 1 253 while True: 254 if current == None: 255 raise IndexError 256 if i <= index: 257 break 258 current = current.getNext() 259 i -= 1 260 return current.getData()
261
262 - def __iter__(self):
263 ''' built-in class method, makes LinkedList objects iterable 264 pre: self 265 post: self.head, first Node on the list''' 266 return self.forward()
267
268 - def __reversed__(self):
269 ''' built-in class method, makes LinkedList objects reverse iterable 270 pre: self 271 post: self.head, first Node on the list''' 272 return self.backward()
273
274 - def __repr__(self):
275 s = ']' 276 current = self.head 277 while current != None: 278 if current.getNext() == None: 279 s = '['+str(current.getData())+s 280 return s 281 s = ', '+str(current.getData())+s 282 current = current.getNext() 283 return '[]'
284
285 - def forward(self):
286 for i in range(self.length): 287 yield self[i]
288
289 - def backward(self):
290 current = self.head 291 while current != None: 292 yield current.getData() 293 current = current.getNext()
294
295 - def __add__(self, otherLinkedList):
296 new_list = self.__class__() 297 new_list.extend(self) 298 new_list.extend(otherLinkedList) 299 return new_list
300 301 302 if __name__ == '__main__': 303 o = LinkedList() 304 for i in range(100): 305 o.append(i) 306 307 for i in reversed(o): 308 print i 309 print 100000 in o 310 311 print o.pop() 312 print o.pop(0) 313 o.insert(0, 'a') 314 print o.pop(0) 315 316 a = o[:50] 317 for i in a: 318 print i 319 a = o[50:] 320 for i in a: 321 print i 322