-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLinkedLeakyStack.py
142 lines (115 loc) · 3.54 KB
/
LinkedLeakyStack.py
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
141
142
class Empty(Exception):
pass
class DoublyLinkedList:
class Node:
def __init__(self, data=None, next=None, prev=None):
self.data = data
self.next = next
self.prev = prev
def disconnect(self):
self.data = None
self.next = None
self.prev = None
def __init__(self):
self.header = DoublyLinkedList.Node()
self.trailer = DoublyLinkedList.Node()
self.header.next = self.trailer
self.trailer.prev = self.header
self.size = 0
def __len__(self):
return self.size
def is_empty(self):
return (len(self) == 0)
def first_node(self):
if (self.is_empty()):
raise Empty("List is empty")
return self.header.next
def last_node(self):
if (self.is_empty()):
raise Empty("List is empty")
return self.trailer.prev
def add_first(self, elem):
return self.add_after(self.header, elem)
def add_last(self, elem):
return self.add_after(self.trailer.prev, elem)
def add_after(self, node, elem):
prev = node
succ = node.next
new_node = DoublyLinkedList.Node()
new_node.data = elem
new_node.prev = prev
new_node.next = succ
prev.next = new_node
succ.prev = new_node
self.size += 1
return new_node
def add_before(self, node, elem):
return self.add_after(node.prev, elem)
def delete(self, node):
prev = node.prev
succ = node.next
prev.next = succ
succ.prev = prev
self.size -= 1
data = node.data
node.disconnect()
return data
def __iter__(self):
if(self.is_empty()):
return
cursor = self.first_node()
while(cursor is not self.trailer):
yield cursor.data
cursor = cursor.next
def __str__(self):
return '[' + '<-->'.join([str(elem) for elem in self]) + ']'
def __repr__(self):
return str(self)
class LinkedStack:
def __init__(self):
self.list = DoublyLinkedList()
self.size = 0
def __len__(self):
return self.size
def is_empty(self):
return self.size == 0
def push(self, e):
self.list.add_first(e)
self.size += 1
def pop(self):
if self.is_empty():
raise Empty("LinkedStack is empty")
value = self.list.delete(self.list.first_node())
self.size -= 1
return value
def top(self):
if self.is_empty():
raise Empty("LinkedStack is empty")
value = self.list.first_node().data
return value
class LeakyStack:
def __init__(self, max_num_of_elems):
self.list = DoublyLinkedList()
self.capacity = max_num_of_elems
def __len__(self):
return len(self.list)
def is_empty(self):
return len(self.list) == 0
def push(self, e):
self.list.add_first(e)
if len(self.list) > self.capacity:
last_node = self.list.trailer.prev
previous = last_node.prev
previous.next = self.list.trailer
self.list.trailer.prev = previous
last_node.disconnect()
def pop(self):
if self.is_empty():
raise Empty("LeakyStack is empty")
value = self.list.delete(self.list.first_node())
return value
def top(self):
if self.is_empty():
raise Empty("LeakyStack is empty")
value = self.list.first_node().data
return value