-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathlinklistbag.py
More file actions
executable file
·140 lines (109 loc) · 3.49 KB
/
linklistbag.py
File metadata and controls
executable file
·140 lines (109 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
__author__ = "streethacker"
#/usr/bin/python
#-*- coding:utf-8 -*-
# Data Structures and Algorithms Using Python
# CHAPTER 6: Linked Structures
# Listing 6.5: linklistbag.py
class _BagIterator:
def __init__(self, theHead):
self._curNode = theHead
def __iter__(self):
return self
def next(self):
"""
It's important to check the empty or null reference situation first.
Because None object has no attribute 'next'. It will cause an excep
-tion.
"""
if self._curNode is None:
raise StopIteration
else:
item = self._curNode.data
self._curNode = self._curNode.next
return item
class _BagListNode:
"""
Defines a private storage class for creating list nodes. There are
only two attributes: data field and next reference field.
"""
def __init__(self, data):
self.data = data
self.next = None
class Bag:
def __init__(self):
"""
The self._size field is used to keep track of the number of items
stored in the bag that is needed by the __len__ method. Technical
-ly, this field is not needed. But it does prevent us from having
to traverse the list to count the number of nodes each time the l
-ength is needed.
"""
self._head = None
self._size = 0
def __len__(self):
return self._size
def __iter__(self):
return _BagIterator(self._head)
def __contains__(self, target):
"""
The contains() method is a simle search of the linked list.
"""
curNode = self._head
while curNode is not None and curNode.data != target:
curNode = curNode.next
return curNode is not None
def add(self, data):
"""
The add() method simply implements the prepend operation, though
we must also increment the item counter(_size) as new items are
added.
"""
newNode = _BagListNode(data)
newNode.next = self._head
self._head = newNode
self._size += 1
def remove(self, data):
"""
The remove operation of the bag has a precondition that the item
must be in the bag in order to be removed. If we make it pass the
assertion, the item counter is decremented to reflect one less it
-em in the bag, the node containing the item is unlinked from the
linked list, and the item is returned as required by the ADT.
"""
preNode = None
curNode = self._head
while curNode is not None and curNode.data != data:
preNode = curNode
curNode = curNode.next
assert curNode is not None, "The item must be in the bag."
self._size -= 1
if curNode is self._head:
self._head = curNode.next
else:
preNode.next = curNode.next
return curNode.data
# try:
# if curNode is self._head:
# self._head = curNode.next
# else:
# preNode.next = curNode.next
# return curNode.data
# except AttributeError, e:
# print "The item must be in the bag."
# print e
# else:
# self._size -= 1
# return curNode.data
def printBagElements(self):
for b in self:
print b
if __name__ == "__main__":
bag = Bag()
bag.add(10)
bag.add(12)
bag.add(36)
bag.add(77)
bag.printBagElements()
bag.remove(12)
print
bag.printBagElements()