mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-05-02 06:46:18 -04:00
🏣 Clean up for arxiv
This commit is contained in:
parent
1b969e7db3
commit
41756cb10c
280 changed files with 2 additions and 11 deletions
41
book/ebook_src/abstract_structures/HashTableClass.py
Executable file
41
book/ebook_src/abstract_structures/HashTableClass.py
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
class HashTable(object):
|
||||
def __init__(self, slots=10):
|
||||
self.slots = slots
|
||||
self.table = []
|
||||
self.create_table()
|
||||
|
||||
def hash_key(self, value):
|
||||
return hash(value)%self.slots
|
||||
|
||||
def create_table(self):
|
||||
for i in range(self.slots):
|
||||
self.table.append([])
|
||||
|
||||
def add_item(self, value):
|
||||
key = self.hash_key(value)
|
||||
self.table[key].append(value)
|
||||
|
||||
def print_table(self):
|
||||
for key in range(len(self.table)):
|
||||
print "Key is %s, value is %s." %(key, self.table[key])
|
||||
|
||||
def find_item(self, item):
|
||||
pos = self.hash_key(item)
|
||||
if item in self.table[pos]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
if __name__ == '__main__':
|
||||
dic = HashTable(5)
|
||||
for i in range(1, 40, 2):
|
||||
dic.add_item(i)
|
||||
|
||||
dic.print_table()
|
||||
assert(dic.find_item(20) == False)
|
||||
assert(dic.find_item(21) == True)
|
47
book/ebook_src/abstract_structures/QueueClass.py
Executable file
47
book/ebook_src/abstract_structures/QueueClass.py
Executable file
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python
|
||||
# Time: 5 min
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
class Queue(object):
|
||||
def __init__(self):
|
||||
self.enq = []
|
||||
self.deq = []
|
||||
|
||||
def enqueue(self, item):
|
||||
return self.enq.append(item)
|
||||
|
||||
def deque(self):
|
||||
if not self.deq:
|
||||
while self.enq:
|
||||
self.deq.append(self.enq.pop())
|
||||
return self.deq.pop()
|
||||
|
||||
def peak(self):
|
||||
if not self.deq:
|
||||
while self.enq:
|
||||
self.deq.append(self.enq.pop())
|
||||
if self.deq:
|
||||
return self.deq[-1]
|
||||
|
||||
def size(self):
|
||||
return len(self.enq) + len(self.deq)
|
||||
|
||||
def isempty(self):
|
||||
return not (self.enq + self.deq)
|
||||
|
||||
if __name__ == '__main__':
|
||||
q = Queue()
|
||||
for i in range(1,11):
|
||||
q.enqueue(i)
|
||||
print 'Size:', q.size()
|
||||
print 'Is empty?', q.isempty()
|
||||
print 'Peak: ', q.peak()
|
||||
print
|
||||
print 'Dequeuing...'
|
||||
for i in range(10):
|
||||
print q.deque()
|
||||
print 'Size:', q.size()
|
||||
print 'Is empty?', q.isempty()
|
||||
print 'Peak: ', q.peak()
|
63
book/ebook_src/abstract_structures/Stack.py
Executable file
63
book/ebook_src/abstract_structures/Stack.py
Executable file
|
@ -0,0 +1,63 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
class Stack(object):
|
||||
def __init__(self):
|
||||
self.content = []
|
||||
self.min_array = []
|
||||
self.min = float('inf')
|
||||
|
||||
def push(self, value):
|
||||
if value < self.min:
|
||||
self.min = value
|
||||
|
||||
self.content.append(value)
|
||||
self.min_array.append(self.min)
|
||||
|
||||
def pop(self):
|
||||
if self.content:
|
||||
value = self.content.pop()
|
||||
self.min_array.pop()
|
||||
if self.min_array:
|
||||
self.min = self.min_array[-1]
|
||||
return value
|
||||
else:
|
||||
return 'Empty List. '
|
||||
|
||||
def find_min(self):
|
||||
if self.min_array:
|
||||
return self.min_array[-1]
|
||||
else:
|
||||
return 'No min value for empty list.'
|
||||
|
||||
def size(self):
|
||||
return len(self.content)
|
||||
|
||||
def isEmpty(self):
|
||||
return not bool(self.content)
|
||||
|
||||
def peek(self):
|
||||
if self.content:
|
||||
return self.content[-1]
|
||||
else:
|
||||
print('Stack is empty.')
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return '{}'.format(self.content)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
q = Stack()
|
||||
|
||||
for i in range(15,20):
|
||||
q.push(i)
|
||||
for i in range(10,5,-1):
|
||||
q.push(i)
|
||||
|
||||
|
||||
|
||||
for i in range(1, 13):
|
||||
print q.pop(), q.find_min()
|
1
book/ebook_src/abstract_structures/__init__.py
Executable file
1
book/ebook_src/abstract_structures/__init__.py
Executable file
|
@ -0,0 +1 @@
|
|||
__all__=["hash_tables", "heap", "linked_list", "queues", "stacks"]
|
0
book/ebook_src/abstract_structures/heap/__init__.py
Normal file
0
book/ebook_src/abstract_structures/heap/__init__.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
import heapq
|
||||
|
||||
def find_N_largest_items_seq(seq, N):
|
||||
''' find the N largest items in a sequence '''
|
||||
return heapq.nlargest(N,seq)
|
||||
|
||||
def find_N_smallest_items_seq(seq, N):
|
||||
''' find the N smallest items in a sequence '''
|
||||
return heapq.nsmallest(N, seq)
|
||||
|
||||
def find_smallest_items_seq_heap(seq):
|
||||
''' find the smallest items in a sequence using heapify first'''
|
||||
''' heap[0] is always the smallest item '''
|
||||
''' pops the smallest item, O(logN) '''
|
||||
heapq.heapify(seq)
|
||||
return heapq.heappop(seq)
|
||||
|
||||
def find_smallest_items_seq(seq):
|
||||
''' if it is only one item, min() is faster '''
|
||||
return min(seq)
|
||||
|
||||
def find_N_smallest_items_seq_sorted(seq, N):
|
||||
''' N ~ len(seq), better sort instead'''
|
||||
return sorted(seq)[:N]
|
||||
|
||||
def find_N_largest_items_seq_sorted(seq, N):
|
||||
''' N ~ len(seq), better sort instead'''
|
||||
return sorted(seq)[len(seq)-N:]
|
||||
|
||||
|
||||
def test_find_N_largest_smallest_items_seq(module_name='this module'):
|
||||
seq = [1, 3, 2, 8, 6, 10, 9]
|
||||
N = 3
|
||||
assert(find_N_largest_items_seq(seq, N) == [10, 9, 8])
|
||||
assert(find_N_largest_items_seq_sorted(seq, N) == [8, 9, 10])
|
||||
assert(find_N_smallest_items_seq(seq, N) == [1,2,3])
|
||||
assert(find_N_smallest_items_seq_sorted(seq, N) == [1,2,3])
|
||||
assert(find_smallest_items_seq(seq) == 1)
|
||||
assert(find_smallest_items_seq_heap(seq) == 1)
|
||||
|
||||
s = 'Tests in {name} have {con}!'
|
||||
print(s.format(name=module_name, con='passed'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_N_largest_smallest_items_seq()
|
||||
|
49
book/ebook_src/abstract_structures/heap/heapify.py
Normal file
49
book/ebook_src/abstract_structures/heap/heapify.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
class Heapify(object):
|
||||
def __init__(self, data=None):
|
||||
self.data = data or []
|
||||
for i in range(len(data)//2, -1, -1):
|
||||
self.__max_heapify__(i)
|
||||
|
||||
def __repr__(self):
|
||||
return '{}'.format(self.data)
|
||||
|
||||
def parent(self, i):
|
||||
return i >> 1
|
||||
|
||||
def left_child(self, i):
|
||||
return (i << 1) + 1
|
||||
|
||||
def right_child(self, i):
|
||||
return (i << 1) + 2 # +2 instead of +1 because it's 0-indexed.
|
||||
|
||||
def __max_heapify__(self, i):
|
||||
largest = i
|
||||
left = self.left_child(i)
|
||||
right = self.right_child(i)
|
||||
n = len(self.data)
|
||||
largest = (left < n and self.data[left] > self.data[i]) and left or i
|
||||
largest = (right < n and self.data[right] > self.data[largest]) and right or largest
|
||||
if i is not largest:
|
||||
self.data[i], self.data[largest] = self.data[largest], self.data[i]
|
||||
self.__max_heapify__(largest)
|
||||
|
||||
def extract_max(self):
|
||||
n = len(self.data)
|
||||
max_element = self.data[0]
|
||||
self.data[0] = self.data[n - 1]
|
||||
self.data = self.data[:n - 1]
|
||||
self.__max_heapify__(0)
|
||||
return max_element
|
||||
|
||||
|
||||
def test_Heapify():
|
||||
l1 = [3, 2, 5, 1, 7, 8, 2]
|
||||
h = Heapify(l1)
|
||||
assert(h.extract_max() == 8)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_Heapify()
|
27
book/ebook_src/abstract_structures/heap/merge_sorted_seqs.py
Normal file
27
book/ebook_src/abstract_structures/heap/merge_sorted_seqs.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
import heapq
|
||||
|
||||
|
||||
def merge_sorted_seq(seq1, seq2):
|
||||
''' merge two sorted sequences with little ovehead. the result
|
||||
will be sorted, which is different of doing just +'''
|
||||
result = []
|
||||
for c in heapq.merge(seq1, seq2):
|
||||
result.append(c)
|
||||
return result
|
||||
|
||||
|
||||
def test_merge_sorted_seq(module_name='this module'):
|
||||
seq1 = [1, 2, 3, 8, 9, 10]
|
||||
seq2 = [2, 3, 4, 5, 6, 7, 9]
|
||||
seq3 = seq1 + seq2
|
||||
assert(merge_sorted_seqseq1, seq2) == sorted(seq3))
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_merge_sorted_seq()
|
||||
|
40
book/ebook_src/abstract_structures/heap/priority_queue.py
Normal file
40
book/ebook_src/abstract_structures/heap/priority_queue.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
import heapq
|
||||
|
||||
class PriorityQueue(object):
|
||||
''' implements a priority queue class '''
|
||||
def __init__(self):
|
||||
self._queue = []
|
||||
self._index = 0 # comparying same priority level
|
||||
|
||||
def push(self, item, priority):
|
||||
heapq.heappush(self._queue, (-priority, self._index, item))
|
||||
self._index += 1
|
||||
|
||||
def pop(self):
|
||||
return heapq.heappop(self._queue)[-1]
|
||||
|
||||
|
||||
class Item:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
def __repr__(self):
|
||||
return "Item({!r})".format(self.name)
|
||||
|
||||
|
||||
def test_PriorityQueue():
|
||||
''' push and pop are all O(logN) '''
|
||||
q = PriorityQueue()
|
||||
q.push(Item('test1'), 1)
|
||||
q.push(Item('test2'), 4)
|
||||
q.push(Item('test3'), 3)
|
||||
assert(str(q.pop()) == "Item('test2')")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_PriorityQueue()
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
''' implement a function to see whether a linked list is circular.
|
||||
To implement this, we just need two pointers with different
|
||||
paces (for example, one goes twice faster)'''
|
||||
|
||||
from linked_list_fifo import LinkedListFIFO
|
||||
from node import Node
|
||||
|
||||
|
||||
class cicularLinkedListFIFO(LinkedListFIFO):
|
||||
def _add(self, value):
|
||||
self.length += 1
|
||||
node = Node(value, self.head)
|
||||
if self.tail:
|
||||
self.tail.pointer = node
|
||||
self.tail = node
|
||||
|
||||
|
||||
|
||||
|
||||
def isCircularll(ll):
|
||||
p1 = ll.head
|
||||
p2 = ll.head
|
||||
|
||||
while p2:
|
||||
try:
|
||||
p1 = p1.pointer
|
||||
p2 = p2.pointer.pointer
|
||||
except:
|
||||
break
|
||||
|
||||
if p1 == p2:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
ll = LinkedListFIFO()
|
||||
for i in range(10):
|
||||
ll.addNode(i)
|
||||
ll._printList()
|
||||
|
||||
print(isCircularll(ll))
|
||||
|
||||
lcirc = cicularLinkedListFIFO()
|
||||
for i in range(10):
|
||||
lcirc.addNode(i)
|
||||
print(isCircularll(lcirc))
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' Implement a double-linked list, which is very simple, we just need inherits
|
||||
from a Linked List Class and add an attribute for previous.'''
|
||||
|
||||
from linked_list_fifo import LinkedListFIFO
|
||||
|
||||
|
||||
class dNode(object):
|
||||
def __init__(self, value=None, pointer=None, previous=None):
|
||||
self.value = value
|
||||
self.pointer = pointer
|
||||
self.previous = previous
|
||||
|
||||
|
||||
class dLinkList(LinkedListFIFO):
|
||||
|
||||
def printListInverse(self):
|
||||
node = self.tail
|
||||
while node:
|
||||
print(node.value)
|
||||
try:
|
||||
node = node.previous
|
||||
except:
|
||||
break
|
||||
|
||||
def _add(self, value):
|
||||
self.length += 1
|
||||
node = dNode(value)
|
||||
if self.tail:
|
||||
self.tail.pointer = node
|
||||
node.previous = self.tail
|
||||
self.tail = node
|
||||
|
||||
def _delete(self, node):
|
||||
self.length -= 1
|
||||
node.previous.pointer = node.pointer
|
||||
if not node.pointer:
|
||||
self.tail = node.previous
|
||||
|
||||
def _find(self, index):
|
||||
node = self.head
|
||||
i = 0
|
||||
while node and i < index:
|
||||
node = node.pointer
|
||||
i += 1
|
||||
return node, i
|
||||
|
||||
# delete nodes in general
|
||||
def deleteNode(self, index):
|
||||
if not self.head or not self.head.pointer:
|
||||
self._deleteFirst()
|
||||
else:
|
||||
node, i = self._find(index)
|
||||
if i == index:
|
||||
self._delete(node)
|
||||
else:
|
||||
print('Node with index {} not found'.format(index))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
from collections import Counter
|
||||
|
||||
ll = dLinkList()
|
||||
for i in range(1, 5):
|
||||
ll.addNode(i)
|
||||
print('Printing the list...')
|
||||
ll._printList()
|
||||
print('Now, printing the list inversely...')
|
||||
ll.printListInverse()
|
||||
print('The list after adding node with value 15')
|
||||
ll._add(15)
|
||||
ll._printList()
|
||||
print("The list after deleting everything...")
|
||||
for i in range(ll.length-1, -1, -1):
|
||||
ll.deleteNode(i)
|
||||
ll._printList()
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
''' Find the mth-to-last element of a linked list.
|
||||
One option is having two pointers, separated by m. P1 start at the roots
|
||||
(p1 = self.root) and p2 is m-behinf pointer, which is created when p1 is at m.
|
||||
When p1 reach the end, p2 is the node. '''
|
||||
|
||||
from linked_list_fifo import LinkedListFIFO
|
||||
from node import Node
|
||||
|
||||
|
||||
class LinkedListFIFO_find_kth(LinkedListFIFO):
|
||||
|
||||
|
||||
def find_kth_to_last(self, k):
|
||||
p1, p2 = self.head, self.head
|
||||
i = 0
|
||||
while p1:
|
||||
if i > k:
|
||||
try:
|
||||
p2 = p2.pointer
|
||||
except:
|
||||
break
|
||||
p1 = p1.pointer
|
||||
i += 1
|
||||
return p2.value
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ll = LinkedListFIFO_find_kth()
|
||||
for i in range(1, 11):
|
||||
ll.addNode(i)
|
||||
print('The Linked List:')
|
||||
print(ll._printList())
|
||||
k = 3
|
||||
k_from_last = ll.find_kth_to_last(k)
|
||||
print("The %dth element to the last of the LL of size %d is %d" %(k, ll.length, k_from_last))
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' A class for a linked list that has the nodes in a FIFO order (such as a queue)'''
|
||||
|
||||
|
||||
from node import Node
|
||||
|
||||
class LinkedListFIFO(object):
|
||||
|
||||
def __init__(self):
|
||||
self.head = None
|
||||
self.length = 0
|
||||
self.tail = None # this is different from ll lifo
|
||||
|
||||
def _printList(self):
|
||||
node = self.head
|
||||
while node:
|
||||
print(node.value)
|
||||
node = node.pointer
|
||||
|
||||
def _addFirst(self, value):
|
||||
self.length = 1
|
||||
node = Node(value)
|
||||
self.head = node
|
||||
self.tail = node
|
||||
|
||||
def _deleteFirst(self):
|
||||
self.length = 0
|
||||
self.head = None
|
||||
self.tail = None
|
||||
print('The list is empty.')
|
||||
|
||||
def _add(self, value):
|
||||
self.length += 1
|
||||
node = Node(value)
|
||||
if self.tail:
|
||||
self.tail.pointer = node
|
||||
self.tail = node
|
||||
|
||||
def addNode(self, value):
|
||||
if not self.head:
|
||||
self._addFirst(value)
|
||||
else:
|
||||
self._add(value)
|
||||
|
||||
def _find(self, index):
|
||||
prev = None
|
||||
node = self.head
|
||||
i = 0
|
||||
while node and i < index:
|
||||
prev = node
|
||||
node = node.pointer
|
||||
i += 1
|
||||
return node, prev, i
|
||||
|
||||
def deleteNode(self, index):
|
||||
if not self.head or not self.head.pointer:
|
||||
self._deleteFirst()
|
||||
else:
|
||||
node, prev, i = self._find(index)
|
||||
if i == index and node:
|
||||
self.length -= 1
|
||||
if i == 0 or not prev :
|
||||
self.head = node.pointer
|
||||
else:
|
||||
prev.pointer = node.pointer
|
||||
if not self.tail == node:
|
||||
self.tail = prev
|
||||
else:
|
||||
print('Node with index {} not found'.format(index))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ll = LinkedListFIFO()
|
||||
for i in range(1, 5):
|
||||
ll.addNode(i)
|
||||
print('The list is:')
|
||||
ll._printList()
|
||||
print('The list after deleting node with index 2:')
|
||||
ll.deleteNode(2)
|
||||
ll._printList()
|
||||
print('The list after adding node with value 15')
|
||||
ll._add(15)
|
||||
ll._printList()
|
||||
print("The list after deleting everything...")
|
||||
for i in range(ll.length-1, -1, -1):
|
||||
ll.deleteNode(i)
|
||||
ll._printList()
|
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
''' Implement a unordered linked list, i.e. a LIFO linked list (like a stack) '''
|
||||
|
||||
from node import Node
|
||||
|
||||
class LinkedListLIFO(object):
|
||||
|
||||
def __init__(self):
|
||||
self.head = None
|
||||
self.length = 0
|
||||
|
||||
def _printList(self):
|
||||
node = self.head
|
||||
while node:
|
||||
print(node.value)
|
||||
node = node.pointer
|
||||
|
||||
def _delete(self, prev, node):
|
||||
self.length -= 1
|
||||
if not prev:
|
||||
self.head = node.pointer
|
||||
else:
|
||||
prev.pointer = node.pointer
|
||||
|
||||
def _add(self, value):
|
||||
self.length += 1
|
||||
self.head = Node(value, self.head)
|
||||
|
||||
def _find(self, index):
|
||||
prev = None
|
||||
node = self.head
|
||||
i = 0
|
||||
while node and i < index:
|
||||
prev = node
|
||||
node = node.pointer
|
||||
i += 1
|
||||
return node, prev, i
|
||||
|
||||
def _find_by_value(self, value):
|
||||
prev = None
|
||||
node = self.head
|
||||
found = 0
|
||||
while node and not found:
|
||||
if node.value == value:
|
||||
found = True
|
||||
else:
|
||||
prev = node
|
||||
node = node.pointer
|
||||
return node, prev, found
|
||||
|
||||
def deleteNode(self, index):
|
||||
node, prev, i = self._find(index)
|
||||
if index == i:
|
||||
self._delete(prev, node)
|
||||
else:
|
||||
print('Node with index {} not found'.format(index))
|
||||
|
||||
def deleteNodeByValue(self, value):
|
||||
node, prev, found = self._find_by_value(value)
|
||||
if found:
|
||||
self._delete(prev, node)
|
||||
else:
|
||||
print('Node with value {} not found'.format(value))
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ll = LinkedListLIFO()
|
||||
for i in range(1, 5):
|
||||
ll._add(i)
|
||||
print('The list is:')
|
||||
ll._printList()
|
||||
print('The list after deleting node with index 2:')
|
||||
ll.deleteNode(2)
|
||||
ll._printList()
|
||||
print('The list after deleting node with value 3:')
|
||||
ll.deleteNodeByValue(2)
|
||||
ll._printList()
|
||||
print('The list after adding node with value 15')
|
||||
ll._add(15)
|
||||
ll._printList()
|
||||
print("The list after deleting everything...")
|
||||
for i in range(ll.length-1, -1, -1):
|
||||
ll.deleteNode(i)
|
||||
ll._printList()
|
33
book/ebook_src/abstract_structures/linked_list/node.py
Normal file
33
book/ebook_src/abstract_structures/linked_list/node.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
class Node(object):
|
||||
def __init__(self, value=None, pointer=None):
|
||||
self.value = value
|
||||
self.pointer = pointer
|
||||
|
||||
def getData(self):
|
||||
return self.value
|
||||
|
||||
def getNext(self):
|
||||
return self.pointer
|
||||
|
||||
def setData(self, newdata):
|
||||
self.value = newdata
|
||||
|
||||
def setNext(self, newpointer):
|
||||
self.pointer = newpointer
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
L = Node("a", Node("b", Node("c", Node("d"))))
|
||||
assert(L.pointer.pointer.value=='c')
|
||||
|
||||
print(L.getData())
|
||||
print(L.getNext().getData())
|
||||
L.setData('aa')
|
||||
L.setNext(Node('e'))
|
||||
print(L.getData())
|
||||
print(L.getNext().getData())
|
|
@ -0,0 +1,57 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' This function divides a linked list in a value, where everything smaller than this value
|
||||
goes to the front, and everything large goes to the back:'''
|
||||
|
||||
|
||||
from linked_list_fifo import LinkedListFIFO
|
||||
from node import Node
|
||||
|
||||
|
||||
def partList(ll, n):
|
||||
|
||||
more = LinkedListFIFO()
|
||||
less = LinkedListFIFO()
|
||||
|
||||
node = ll.head
|
||||
|
||||
while node:
|
||||
item = node.value
|
||||
|
||||
if item < n:
|
||||
less.addNode(item)
|
||||
|
||||
elif item > n:
|
||||
more.addNode(item)
|
||||
|
||||
node = node.pointer
|
||||
|
||||
less.addNode(n)
|
||||
nodemore = more.head
|
||||
|
||||
while nodemore:
|
||||
less.addNode(nodemore.value)
|
||||
nodemore = nodemore.pointer
|
||||
|
||||
return less
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
ll = LinkedListFIFO()
|
||||
l = [6, 7, 3, 4, 9, 5, 1, 2, 8]
|
||||
for i in l:
|
||||
ll.addNode(i)
|
||||
|
||||
print('Before Part')
|
||||
ll._printList()
|
||||
|
||||
print('After Part')
|
||||
newll = partList(ll, 6)
|
||||
newll._printList()
|
||||
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' Supposing two linked lists representing numbers, such that in each of their
|
||||
nodes they carry one digit. This function sums the two numbers that these
|
||||
two linked lists represent, returning a third list representing the sum:'''
|
||||
|
||||
|
||||
from linked_list_fifo import LinkedListFIFO
|
||||
from node import Node
|
||||
|
||||
|
||||
class LinkedListFIFOYield(LinkedListFIFO):
|
||||
|
||||
# print each node's value, starting from the head
|
||||
def _printList(self):
|
||||
node = self.head
|
||||
while node:
|
||||
yield(node.value)
|
||||
node = node.pointer
|
||||
|
||||
|
||||
|
||||
def sumlls(l1, l2):
|
||||
|
||||
lsum = LinkedListFIFOYield()
|
||||
dig1 = l1.head
|
||||
dig2 = l2.head
|
||||
pointer = 0
|
||||
|
||||
while dig1 and dig2:
|
||||
d1 = dig1.value
|
||||
d2 = dig2.value
|
||||
sum_d = d1 + d2 + pointer
|
||||
if sum_d > 9:
|
||||
pointer = sum_d//10
|
||||
lsum.addNode(sum_d%10)
|
||||
|
||||
else:
|
||||
lsum.addNode(sum_d)
|
||||
pointer = 0
|
||||
|
||||
dig1 = dig1.pointer
|
||||
dig2 = dig2.pointer
|
||||
|
||||
if dig1:
|
||||
sum_d = pointer + dig1.value
|
||||
if sum_d > 9:
|
||||
lsum.addNode(sum_d%10)
|
||||
else:
|
||||
lsum.addNode(sum_d)
|
||||
dig1 = dig1.pointer
|
||||
|
||||
if dig2:
|
||||
sum_d = pointer + dig2.value
|
||||
if sum_d > 9:
|
||||
lsum.addNode(sum_d%10)
|
||||
else:
|
||||
lsum.addNode(sum_d)
|
||||
dig2 = dig2.pointer
|
||||
|
||||
return lsum
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
l1 = LinkedListFIFOYield() # 2671
|
||||
l1.addNode(1)
|
||||
l1.addNode(7)
|
||||
l1.addNode(6)
|
||||
l1.addNode(2)
|
||||
|
||||
l2 = LinkedListFIFOYield() # 455
|
||||
l2.addNode(5)
|
||||
l2.addNode(5)
|
||||
l2.addNode(4)
|
||||
|
||||
lsum = sumlls(l1, l2)
|
||||
l = list(lsum._printList())
|
||||
for i in reversed(l):
|
||||
print i
|
0
book/ebook_src/abstract_structures/queues/__init__.py
Normal file
0
book/ebook_src/abstract_structures/queues/__init__.py
Normal file
109
book/ebook_src/abstract_structures/queues/animal_shelter.py
Normal file
109
book/ebook_src/abstract_structures/queues/animal_shelter.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
""" A class for an animal shelter with two queues"""
|
||||
|
||||
|
||||
class Node(object):
|
||||
def __init__(self, animalName=None, animalKind=None, pointer=None):
|
||||
self.animalName = animalName
|
||||
self.animalKind = animalKind
|
||||
self.pointer = pointer
|
||||
self.timestamp = 0
|
||||
|
||||
|
||||
|
||||
class AnimalShelter(object):
|
||||
def __init__(self):
|
||||
self.headCat = None
|
||||
self.headDog = None
|
||||
self.tailCat = None
|
||||
self.tailDog = None
|
||||
self.animalNumber = 0
|
||||
|
||||
|
||||
# Queue any animal
|
||||
|
||||
def enqueue(self, animalName, animalKind):
|
||||
self.animalNumber += 1
|
||||
newAnimal = Node(animalName, animalKind)
|
||||
newAnimal.timestamp = self.animalNumber
|
||||
|
||||
if animalKind == 'cat':
|
||||
if not self.headCat:
|
||||
self.headCat = newAnimal
|
||||
if self.tailCat:
|
||||
self.tailCat.pointer = newAnimal
|
||||
self.tailCat = newAnimal
|
||||
|
||||
elif animalKind == 'dog':
|
||||
if not self.headDog:
|
||||
self.headDog = newAnimal
|
||||
if self.tailDog:
|
||||
self.tailDog.pointer = newAnimal
|
||||
self.tailDog = newAnimal
|
||||
|
||||
|
||||
# Dequeue methods
|
||||
|
||||
def dequeueDog(self):
|
||||
if self.headDog:
|
||||
newAnimal = self.headDog
|
||||
self.headDog = newAnimal.pointer
|
||||
return str(newAnimal.animalName)
|
||||
else:
|
||||
return 'No Dogs!'
|
||||
|
||||
|
||||
def dequeueCat(self):
|
||||
if self.headCat:
|
||||
newAnimal = self.headCat
|
||||
self.headCat = newAnimal.pointer
|
||||
return str(newAnimal.animalName)
|
||||
else:
|
||||
return 'No Cats!'
|
||||
|
||||
|
||||
def dequeueAny(self):
|
||||
if self.headCat and not self.headDog:
|
||||
return self.dequeueCat()
|
||||
elif self.headDog and not self.headCat:
|
||||
return self.dequeueDog()
|
||||
elif self.headDog and self.headCat:
|
||||
if self.headDog.timestamp < self.headCat.timestamp:
|
||||
return self.dequeueDog()
|
||||
else:
|
||||
return self.dequeueCat()
|
||||
else:
|
||||
return ('No Animals!')
|
||||
|
||||
|
||||
|
||||
def _print(self):
|
||||
print("Cats:")
|
||||
cats = self.headCat
|
||||
while cats:
|
||||
print(cats.animalName, cats.animalKind)
|
||||
cats = cats.pointer
|
||||
print("Dogs:")
|
||||
dogs = self.headDog
|
||||
while dogs:
|
||||
print(dogs.animalName, dogs.animalKind)
|
||||
dogs = dogs.pointer
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
qs = AnimalShelter()
|
||||
qs.enqueue('bob', 'cat')
|
||||
qs.enqueue('mia', 'cat')
|
||||
qs.enqueue('yoda', 'dog')
|
||||
qs.enqueue('wolf', 'dog')
|
||||
qs._print()
|
||||
|
||||
print("Deque one dog and one cat...")
|
||||
qs.dequeueDog()
|
||||
qs.dequeueCat()
|
||||
qs._print()
|
39
book/ebook_src/abstract_structures/queues/deque.py
Normal file
39
book/ebook_src/abstract_structures/queues/deque.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' a class for a double ended queue (also inefficient) '''
|
||||
|
||||
from queue import Queue
|
||||
|
||||
class Deque(Queue):
|
||||
|
||||
def enqueue_back(self, item):
|
||||
self.items.append(item)
|
||||
|
||||
def dequeue_front(self):
|
||||
return self.items.pop(0)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
queue = Deque()
|
||||
print("Is the queue empty? ", queue.isEmpty())
|
||||
print("Adding 0 to 10 in the queue...")
|
||||
for i in range(10):
|
||||
queue.enqueue(i)
|
||||
print("Queue size: ", queue.size())
|
||||
print("Queue peek : ", queue.peek())
|
||||
print("Dequeue...", queue.dequeue())
|
||||
print("Queue peek: ", queue.peek())
|
||||
print("Is the queue empty? ", queue.isEmpty())
|
||||
print(queue)
|
||||
|
||||
print("\nNow using the dequeue methods...")
|
||||
print("Dequeue from front...", queue.dequeue_front())
|
||||
print("Queue peek: ", queue.peek())
|
||||
print(queue)
|
||||
print("Queue from back...")
|
||||
queue.enqueue_back(50)
|
||||
print("Queue peek: ", queue.peek())
|
||||
print(queue)
|
80
book/ebook_src/abstract_structures/queues/linked_queue.py
Normal file
80
book/ebook_src/abstract_structures/queues/linked_queue.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' Queue acts as a container for nodes (objects) that are inserted and removed according FIFO'''
|
||||
|
||||
|
||||
class Node(object):
|
||||
def __init__(self, value=None, pointer=None):
|
||||
self.value = value
|
||||
self.pointer = None
|
||||
|
||||
|
||||
class LinkedQueue(object):
|
||||
def __init__(self):
|
||||
self.head = None
|
||||
self.tail = None
|
||||
|
||||
|
||||
def isEmpty(self):
|
||||
return not bool(self.head)
|
||||
|
||||
|
||||
def dequeue(self):
|
||||
if self.head:
|
||||
value = self.head.value
|
||||
self.head = self.head.pointer
|
||||
return value
|
||||
else:
|
||||
print('Queue is empty, cannot dequeue.')
|
||||
|
||||
|
||||
def enqueue(self, value):
|
||||
node = Node(value)
|
||||
if not self.head:
|
||||
self.head = node
|
||||
self.tail = node
|
||||
else:
|
||||
if self.tail:
|
||||
self.tail.pointer = node
|
||||
self.tail = node
|
||||
|
||||
|
||||
def size(self):
|
||||
node = self.head
|
||||
num_nodes = 0
|
||||
while node:
|
||||
num_nodes += 1
|
||||
node = node.pointer
|
||||
return num_nodes
|
||||
|
||||
|
||||
def peek(self):
|
||||
return self.head.value
|
||||
|
||||
|
||||
def _print(self):
|
||||
node = self.head
|
||||
while node:
|
||||
print(node.value)
|
||||
node = node.pointer
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
queue = LinkedQueue()
|
||||
print("Is the queue empty? ", queue.isEmpty())
|
||||
print("Adding 0 to 10 in the queue...")
|
||||
for i in range(10):
|
||||
queue.enqueue(i)
|
||||
print("Is the queue empty? ", queue.isEmpty())
|
||||
queue._print()
|
||||
|
||||
print("Queue size: ", queue.size())
|
||||
print("Queue peek : ", queue.peek())
|
||||
print("Dequeue...", queue.dequeue())
|
||||
print("Queue peek: ", queue.peek())
|
||||
queue._print()
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
""" Using our deque class and Python's deque class """
|
||||
|
||||
|
||||
import string
|
||||
import collections
|
||||
|
||||
from deque import Deque
|
||||
|
||||
|
||||
STRIP = string.whitespace + string.punctuation + "\"'"
|
||||
|
||||
def palindrome_checker_with_deque(str1):
|
||||
|
||||
d1 = Deque()
|
||||
d2 = collections.deque()
|
||||
|
||||
for s in str1.lower():
|
||||
if s not in STRIP:
|
||||
d2.append(s)
|
||||
d1.enqueue(s)
|
||||
|
||||
|
||||
eq1 = True
|
||||
while d1.size() > 1 and eq1:
|
||||
if d1.dequeue_front() != d1.dequeue():
|
||||
eq1 = False
|
||||
|
||||
eq2 = True
|
||||
while len(d2) > 1 and eq2:
|
||||
if d2.pop() != d2.popleft():
|
||||
eq2 = False
|
||||
|
||||
return eq1, eq2
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
str1 = 'Madam Im Adam'
|
||||
str2 = 'Buffy is a Slayer'
|
||||
print(palindrome_checker_with_deque(str1))
|
||||
print(palindrome_checker_with_deque(str2))
|
63
book/ebook_src/abstract_structures/queues/queue.py
Normal file
63
book/ebook_src/abstract_structures/queues/queue.py
Normal file
|
@ -0,0 +1,63 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
class Queue(object):
|
||||
|
||||
def __init__(self):
|
||||
self.in_stack = []
|
||||
self.out_stack = []
|
||||
|
||||
def _transfer(self):
|
||||
while self.in_stack:
|
||||
self.out_stack.append(self.in_stack.pop())
|
||||
|
||||
def enqueue(self, item):
|
||||
return self.in_stack.append(item)
|
||||
|
||||
def dequeue(self):
|
||||
if not self.out_stack:
|
||||
self._transfer()
|
||||
if self.out_stack:
|
||||
return self.out_stack.pop()
|
||||
else:
|
||||
return "Queue empty!"
|
||||
|
||||
def size(self):
|
||||
return len(self.in_stack) + len(self.out_stack)
|
||||
|
||||
def peek(self):
|
||||
if not self.out_stack:
|
||||
self._transfer()
|
||||
if self.out_stack:
|
||||
return self.out_stack[-1]
|
||||
else:
|
||||
return "Queue empty!"
|
||||
|
||||
def __repr__(self):
|
||||
if not self.out_stack:
|
||||
self._transfer()
|
||||
if self.out_stack:
|
||||
return '{}'.format(self.out_stack)
|
||||
else:
|
||||
return "Queue empty!"
|
||||
|
||||
def isEmpty(self):
|
||||
return not (bool(self.in_stack) or bool(self.out_stack))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
queue = Queue()
|
||||
print("Is the queue empty? ", queue.isEmpty())
|
||||
print("Adding 0 to 10 in the queue...")
|
||||
for i in range(10):
|
||||
queue.enqueue(i)
|
||||
print("Queue size: ", queue.size())
|
||||
print("Queue peek : ", queue.peek())
|
||||
print("Dequeue...", queue.dequeue())
|
||||
print("Queue peek: ", queue.peek())
|
||||
print("Is the queue empty? ", queue.isEmpty())
|
||||
|
||||
print("Printing the queue...")
|
||||
print(queue)
|
0
book/ebook_src/abstract_structures/stacks/__init__.py
Normal file
0
book/ebook_src/abstract_structures/stacks/__init__.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
'''transform a decimal number to a binary number with a stack '''
|
||||
|
||||
|
||||
from stack import Stack
|
||||
|
||||
def dec2bin_with_stack(decnum):
|
||||
|
||||
s = Stack()
|
||||
str_aux = ''
|
||||
|
||||
while decnum > 0:
|
||||
dig = decnum % 2
|
||||
decnum = decnum//2
|
||||
s.push(dig)
|
||||
|
||||
while not s.isEmpty():
|
||||
str_aux += str(s.pop())
|
||||
|
||||
return str_aux
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
decnum = 9
|
||||
assert(dec2bin_with_stack(decnum) == '1001')
|
71
book/ebook_src/abstract_structures/stacks/linked_stack.py
Normal file
71
book/ebook_src/abstract_structures/stacks/linked_stack.py
Normal file
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
""" A stack made of linked list"""
|
||||
|
||||
|
||||
class Node(object):
|
||||
def __init__(self, value=None, pointer=None):
|
||||
self.value = value
|
||||
self.pointer = pointer
|
||||
|
||||
|
||||
class Stack(object):
|
||||
def __init__(self):
|
||||
self.head = None
|
||||
|
||||
def isEmpty(self):
|
||||
return not bool(self.head)
|
||||
|
||||
def push(self, item):
|
||||
self.head = Node(item, self.head)
|
||||
|
||||
|
||||
def pop(self):
|
||||
if self.head:
|
||||
node = self.head
|
||||
self.head = node.pointer
|
||||
return node.value
|
||||
else:
|
||||
print('Stack is empty.')
|
||||
|
||||
|
||||
def peek(self):
|
||||
if self.head:
|
||||
return self.head.value
|
||||
else:
|
||||
print('Stack is empty.')
|
||||
|
||||
|
||||
def size(self):
|
||||
node = self.head
|
||||
count = 0
|
||||
while node:
|
||||
count +=1
|
||||
node = node.pointer
|
||||
return count
|
||||
|
||||
|
||||
def _printList(self):
|
||||
node = self.head
|
||||
while node:
|
||||
print(node.value)
|
||||
node = node.pointer
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
stack = Stack()
|
||||
print("Is the stack empty? ", stack.isEmpty())
|
||||
print("Adding 0 to 10 in the stack...")
|
||||
for i in range(10):
|
||||
stack.push(i)
|
||||
stack._printList()
|
||||
print("Stack size: ", stack.size())
|
||||
print("Stack peek : ", stack.peek())
|
||||
print("Pop...", stack.pop())
|
||||
print("Stack peek: ", stack.peek())
|
||||
print("Is the stack empty? ", stack.isEmpty())
|
||||
stack._printList()
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
''' Uses a stack to reverse a string '''
|
||||
|
||||
from stack import Stack
|
||||
|
||||
def reverse_string_with_stack(str1):
|
||||
|
||||
s = Stack()
|
||||
revStr = ''
|
||||
|
||||
for c in str1:
|
||||
s.push(c)
|
||||
|
||||
while not s.isEmpty():
|
||||
revStr += s.pop()
|
||||
|
||||
return revStr
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
str1 = 'Buffy is a Slayer!'
|
||||
print(str1)
|
||||
print(reverse_string_with_stack(str1))
|
||||
|
||||
|
||||
|
56
book/ebook_src/abstract_structures/stacks/set_of_stacks.py
Normal file
56
book/ebook_src/abstract_structures/stacks/set_of_stacks.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
""" define a class for a set of stacks """
|
||||
|
||||
from stack import Stack
|
||||
|
||||
class SetOfStacks(Stack):
|
||||
def __init__(self, capacity=4):
|
||||
self.setofstacks = []
|
||||
self.items = []
|
||||
self.capacity = capacity
|
||||
|
||||
|
||||
def push(self, value):
|
||||
if self.size() >= self.capacity:
|
||||
self.setofstacks.append(self.items)
|
||||
self.items = []
|
||||
self.items.append(value)
|
||||
|
||||
|
||||
def pop(self):
|
||||
value = self.items.pop()
|
||||
if self.isEmpty() and self.setofstacks:
|
||||
self.items = self.setofstacks.pop()
|
||||
return value
|
||||
|
||||
|
||||
def sizeStack(self):
|
||||
return len(self.setofstacks)*self.capacity + self.size()
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
aux = []
|
||||
for s in self.setofstacks:
|
||||
aux.extend(s)
|
||||
aux.extend(self.items)
|
||||
return '{}'.format(aux)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
capacity = 5
|
||||
stack = SetOfStacks(capacity)
|
||||
print("Is the stack empty? ", stack.isEmpty())
|
||||
print("Adding 0 to 10 in the stack...")
|
||||
for i in range(10):
|
||||
stack.push(i)
|
||||
print(stack)
|
||||
print("Stack size: ", stack.sizeStack())
|
||||
print("Stack peek : ", stack.peek())
|
||||
print("Pop...", stack.pop())
|
||||
print("Stack peek: ", stack.peek())
|
||||
print("Is the stack empty? ", stack.isEmpty())
|
||||
print(stack)
|
65
book/ebook_src/abstract_structures/stacks/stack.py
Executable file
65
book/ebook_src/abstract_structures/stacks/stack.py
Executable file
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# copy of the class ../Stack.py
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
class Stack(object):
|
||||
def __init__(self):
|
||||
self.content = []
|
||||
self.min_array = []
|
||||
self.min = float('inf')
|
||||
|
||||
def push(self, value):
|
||||
if value < self.min:
|
||||
self.min = value
|
||||
|
||||
self.content.append(value)
|
||||
self.min_array.append(self.min)
|
||||
|
||||
def pop(self):
|
||||
if self.content:
|
||||
value = self.content.pop()
|
||||
self.min_array.pop()
|
||||
if self.min_array:
|
||||
self.min = self.min_array[-1]
|
||||
return value
|
||||
else:
|
||||
return 'Empty List. '
|
||||
|
||||
def find_min(self):
|
||||
if self.min_array:
|
||||
return self.min_array[-1]
|
||||
else:
|
||||
return 'No min value for empty list.'
|
||||
|
||||
def size(self):
|
||||
return len(self.content)
|
||||
|
||||
def isEmpty(self):
|
||||
return not bool(self.content)
|
||||
|
||||
def peek(self):
|
||||
if self.content:
|
||||
return self.content[-1]
|
||||
else:
|
||||
print('Stack is empty.')
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return '{}'.format(self.content)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
q = Stack()
|
||||
|
||||
for i in range(15,20):
|
||||
q.push(i)
|
||||
for i in range(10,5,-1):
|
||||
q.push(i)
|
||||
|
||||
|
||||
|
||||
for i in range(1, 13):
|
||||
print q.pop(), q.find_min()
|
77
book/ebook_src/abstract_structures/stacks/stack_with_min.py
Normal file
77
book/ebook_src/abstract_structures/stacks/stack_with_min.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' A stack with a minimum lookup '''
|
||||
|
||||
from stack import Stack
|
||||
|
||||
|
||||
class NodeWithMin(object):
|
||||
def __init__(self, value=None, minimum=None):
|
||||
self.value = value
|
||||
self.minimum = minimum
|
||||
|
||||
|
||||
class StackMin(Stack):
|
||||
def __init__(self):
|
||||
self.items = []
|
||||
self.minimum = None
|
||||
|
||||
|
||||
def push(self, value):
|
||||
if self.isEmpty() or self.minimum > value:
|
||||
self.minimum = value
|
||||
self.items.append(NodeWithMin(value, self.minimum))
|
||||
|
||||
|
||||
def peek(self):
|
||||
return self.items[-1].value
|
||||
|
||||
|
||||
def peekMinimum(self):
|
||||
return self.items[-1].minimum
|
||||
|
||||
|
||||
def pop(self):
|
||||
item = self.items.pop()
|
||||
if item:
|
||||
if item.value == self.minimum:
|
||||
self.minimum = self.peekMinimum()
|
||||
return item.value
|
||||
else:
|
||||
print("Stack is empty.")
|
||||
|
||||
def __repr__(self):
|
||||
aux = []
|
||||
for i in self.items:
|
||||
aux.append(i.value)
|
||||
return '{}'.format(aux)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
stack = StackMin()
|
||||
print("Is the stack empty? ", stack.isEmpty())
|
||||
print("Adding 0 to 10 in the stack...")
|
||||
for i in range(10,3, -1):
|
||||
stack.push(i)
|
||||
print(stack)
|
||||
|
||||
print("Stack size: ", stack.size())
|
||||
print("Stack peek and peekMinimum : ", stack.peek(), stack.peekMinimum())
|
||||
print("Pop...", stack.pop())
|
||||
print("Stack peek and peekMinimum : ", stack.peek(), stack.peekMinimum())
|
||||
print("Is the stack empty? ", stack.isEmpty())
|
||||
print(stack)
|
||||
|
||||
for i in range(5, 1, -1):
|
||||
stack.push(i)
|
||||
print(stack)
|
||||
|
||||
print("Stack size: ", stack.size())
|
||||
print("Stack peek and peekMinimum : ", stack.peek(), stack.peekMinimum())
|
||||
print("Pop...", stack.pop())
|
||||
print("Stack peek and peekMinimum : ", stack.peek(), stack.peekMinimum())
|
||||
print("Is the stack empty? ", stack.isEmpty())
|
||||
print(stack)
|
41
book/ebook_src/abstract_structures/stacks/towers_of_hanoi.py
Normal file
41
book/ebook_src/abstract_structures/stacks/towers_of_hanoi.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
""" Implement the 'towers of hanoi'"""
|
||||
|
||||
from linked_stack import Stack, Node
|
||||
|
||||
|
||||
def moveTop(s1, s3):
|
||||
|
||||
s3.append(s1.pop())
|
||||
|
||||
|
||||
def moveDisks(n, s1, s3, s2):
|
||||
|
||||
if n < 1: return
|
||||
moveDisks(n - 1, s1, s2, s3)
|
||||
moveTop(s1, s3)
|
||||
moveDisks(n -1, s2, s3, s1)
|
||||
|
||||
|
||||
|
||||
def towersOfHanoi(n):
|
||||
s1 = [x+1 for x in range(n)]
|
||||
s2 = []
|
||||
s3 = []
|
||||
print('The first stick is {0} and the third stick has {1}'.format(s1, s3))
|
||||
|
||||
moveDisks(n, s1, s3, s2)
|
||||
|
||||
print('The first stick is {0} and the third stick has {1}'.format(s1, s3))
|
||||
|
||||
return s3
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
towersOfHanoi(6)
|
Loading…
Add table
Add a link
Reference in a new issue