mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-08-03 12:06:45 -04:00
bk
This commit is contained in:
parent
1e9fdfbbfd
commit
5107f16df0
96 changed files with 17 additions and 1702 deletions
40
src/further_examples/linked_list/check_pal.py
Normal file
40
src/further_examples/linked_list/check_pal.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' Given a linked list, check if the nodes form a palindrome '''
|
||||
|
||||
from linked_list_fifo import LinkList, Node
|
||||
|
||||
def isPal(l1):
|
||||
if len(l1) < 2: return True
|
||||
if l1[0] != l1[-1]: return False
|
||||
return isPal(l1[1:-1])
|
||||
|
||||
|
||||
|
||||
def checkllPal(ll):
|
||||
node = ll.head
|
||||
l1 = []
|
||||
while node:
|
||||
l1.append(node.value)
|
||||
node = node.next
|
||||
return isPal(l1)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
ll = LinkList()
|
||||
l1 = [1, 2, 3, 2, 1]
|
||||
for i in l1:
|
||||
ll.addNode(i)
|
||||
print(checkllPal(ll))
|
||||
|
||||
ll.addNode(2)
|
||||
ll.addNode(3)
|
||||
print(checkllPal(ll))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
72
src/further_examples/linked_list/circ_ll.py
Normal file
72
src/further_examples/linked_list/circ_ll.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
''' Build a class for a circular linked list and implement a function to see whether
|
||||
a linked list is circular'''
|
||||
|
||||
from linked_list_fifo import Node, LinkList
|
||||
|
||||
class Node(object):
|
||||
def __init__(self, value = None, next = None):
|
||||
self.value = value
|
||||
self.next = next
|
||||
|
||||
|
||||
class CircLinkList(object):
|
||||
def __init__(self):
|
||||
self.head = None
|
||||
self.tail = None
|
||||
self.lenght = 0
|
||||
|
||||
def addNode(self, value):
|
||||
node = Node(value, self.head)
|
||||
if not self.head:
|
||||
self.head = node
|
||||
if self.tail:
|
||||
self.tail.next = node
|
||||
self.tail = node
|
||||
self.lenght += 1
|
||||
|
||||
def printList(self):
|
||||
size = self.lenght
|
||||
node = self.head
|
||||
i = 0
|
||||
while i < size:
|
||||
print(node.value)
|
||||
node = node.next
|
||||
i += 1
|
||||
|
||||
|
||||
|
||||
def isCircularll(ll):
|
||||
p1 = ll.head
|
||||
p2 = ll.head
|
||||
|
||||
while p2 and p2.next:
|
||||
p1 = p1.next
|
||||
p2 = p2.next.next
|
||||
|
||||
if p1 == p2:
|
||||
return True
|
||||
return False
|
||||
|
||||
def main():
|
||||
ll = CircLinkList()
|
||||
for i in range(10):
|
||||
ll.addNode(i)
|
||||
ll.printList()
|
||||
|
||||
print(isCircularll(ll))
|
||||
|
||||
ll2 = LinkList()
|
||||
for i in range(10):
|
||||
ll2.addNode(i)
|
||||
ll2.printList()
|
||||
|
||||
print(isCircularll(ll2))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
53
src/further_examples/linked_list/double_linked_list_fifo.py
Normal file
53
src/further_examples/linked_list/double_linked_list_fifo.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' Implement a double-linked list, which is very simple, we just need inherets from a Linked List Class and add an attribute for prev.'''
|
||||
|
||||
from linked_list_fifo import LinkList
|
||||
|
||||
class dNode(object):
|
||||
def __init__(self, value = None, next = None):
|
||||
self.value = value
|
||||
self.next = next
|
||||
self.prev = None # THIS IS THE EXTRA ATTRIBUTE FOR DOUBLE L
|
||||
self.children = None # THIS IS NOT USED HERE, IS EXAMPLES WITH MANY LL INSIDE LLs
|
||||
|
||||
class dLinkList(LinkList):
|
||||
|
||||
def addNode(self, value):
|
||||
node = dNode(value)
|
||||
if not self.head:
|
||||
self.head = node
|
||||
if self.tail:
|
||||
node.prev = self.tail # ADD THIS WHEN DOUBLE L
|
||||
self.tail.next = node
|
||||
self.tail = node
|
||||
self.length += 1
|
||||
|
||||
|
||||
def printListInverse(self): # THIS IS THE EXTRA METHOD FOR DOUBLE L
|
||||
node = self.tail
|
||||
while node:
|
||||
print(node.value)
|
||||
node = node.prev
|
||||
|
||||
|
||||
|
||||
|
||||
from collections import Counter
|
||||
|
||||
def main():
|
||||
|
||||
ll = dLinkList()
|
||||
for i in range(1, 10):
|
||||
ll.addNode(i)
|
||||
print('Printing the list...')
|
||||
ll.printList()
|
||||
print('Now, printing the list inversely...')
|
||||
ll.printListInverse()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
105
src/further_examples/linked_list/find_kth.py
Normal file
105
src/further_examples/linked_list/find_kth.py
Normal file
|
@ -0,0 +1,105 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' 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 Node
|
||||
|
||||
class LinkList(object):
|
||||
def __init__(self):
|
||||
self.head = None
|
||||
self.tail = None
|
||||
self.lenght = 0
|
||||
|
||||
def addNode(self, value):
|
||||
node = Node(value)
|
||||
if not self.head:
|
||||
self.head = node
|
||||
if self.tail:
|
||||
self.tail.next = node
|
||||
self.tail = node
|
||||
self.lenght += 1
|
||||
|
||||
def removeNode(self, index):
|
||||
prev = None
|
||||
node = self.head
|
||||
i = 0
|
||||
while node and i < index:
|
||||
prev = node
|
||||
node = node.next
|
||||
i += 1
|
||||
if i == index:
|
||||
if not prev:
|
||||
self.head = node.next
|
||||
else:
|
||||
prev.next = node.next
|
||||
self.lenght -= 1
|
||||
else:
|
||||
print('Index not found')
|
||||
|
||||
def findkth_from_begin(self, k):
|
||||
node = self.head
|
||||
i = 0
|
||||
while node and i < k:
|
||||
node = node.next
|
||||
i += 1
|
||||
while node:
|
||||
print(node.value)
|
||||
node = node.next
|
||||
|
||||
def findkth_to_last(self, k):
|
||||
node = self.head
|
||||
key = self.lenght - k
|
||||
i = 0
|
||||
while node and i < key:
|
||||
node = node.next
|
||||
i += 1
|
||||
print(node.value)
|
||||
|
||||
def findkth_to_last_2pointers(self, k):
|
||||
node = self.head
|
||||
pointer = self.head
|
||||
i = 0
|
||||
while pointer and i < k:
|
||||
pointer = pointer.next
|
||||
i += 1
|
||||
while pointer:
|
||||
node = node.next
|
||||
pointer = pointer.next
|
||||
print(node.value)
|
||||
|
||||
def findkth_to_last_2pointers2(self, k):
|
||||
p1 = self.head
|
||||
p2 = self.head
|
||||
i = 0
|
||||
while p1:
|
||||
if i >= k: # ---> notice >= not >!
|
||||
p2 = p2.next
|
||||
p1 = p1.next
|
||||
i += 1
|
||||
print(p2.value)
|
||||
|
||||
|
||||
def main():
|
||||
ll = LinkList()
|
||||
for i in range(1, 11):
|
||||
ll.addNode(i)
|
||||
# list is 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
|
||||
# so 0th from last is 11, 1th to last is 10,
|
||||
# 2th from last is 9!
|
||||
|
||||
|
||||
print('Finding from begin...')
|
||||
ll.findkth_from_begin(2)
|
||||
print('Finding to last, case 1...')
|
||||
ll.findkth_to_last(2) #9
|
||||
print('Finding to last, case 2...')
|
||||
ll.findkth_to_last_2pointers(2)
|
||||
print('Finding to last, case 3...')
|
||||
ll.findkth_to_last_2pointers2(2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
65
src/further_examples/linked_list/hash_table.py
Normal file
65
src/further_examples/linked_list/hash_table.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' The first example design a Hash table using chaining to avoid collisions. The second
|
||||
uses two lists.'''
|
||||
|
||||
from linked_list_fifo import Node, LinkList
|
||||
|
||||
class HashTableLL(object):
|
||||
def __init__(self, size):
|
||||
self.size = size
|
||||
self.slots = []
|
||||
self._createHashTable()
|
||||
|
||||
def _createHashTable(self):
|
||||
for i in range(self.size) :
|
||||
self.slots.append(LinkList())
|
||||
|
||||
def findIndex(self, item):
|
||||
return item%self.size
|
||||
|
||||
def addItem(self, item):
|
||||
index = self.findIndex(item)
|
||||
self.slots[index].addNode(item)
|
||||
return self
|
||||
|
||||
|
||||
def delItem(self, item):
|
||||
index = self.findIndex(item)
|
||||
self.slots[index].deleteNode(item)
|
||||
return self
|
||||
|
||||
|
||||
def printHashTable(self):
|
||||
for i in range(self.size):
|
||||
print('\nSlot {}:'.format(i))
|
||||
print(self.slots[i].printList())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_hash_tables():
|
||||
H1 = HashTableLL(3)
|
||||
for i in range (0, 20):
|
||||
H1.addItem(i)
|
||||
H1.printHashTable()
|
||||
print('\n\nNow deleting:')
|
||||
H1.delItem(0)
|
||||
H1.delItem(0)
|
||||
H1.delItem(0)
|
||||
H1.delItem(0)
|
||||
H1.printHashTable()
|
||||
'''
|
||||
H2 = HashTable2L(3)
|
||||
H2[54]="buffy"
|
||||
H2[26]="xander"
|
||||
H2[17]="giles"
|
||||
print(H.2slots)
|
||||
'''
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_hash_tables()
|
183
src/further_examples/linked_list/linked_list_fifo.py
Normal file
183
src/further_examples/linked_list/linked_list_fifo.py
Normal file
|
@ -0,0 +1,183 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' A class for a linked list that has the nodes in a FIFO order (such as a queue)'''
|
||||
|
||||
|
||||
class Node(object):
|
||||
def __init__(self, value = None, next = None):
|
||||
self.value = value
|
||||
self.next = next
|
||||
|
||||
class LinkList(object):
|
||||
def __init__(self):
|
||||
self.head = None
|
||||
self.tail = None
|
||||
self.length = 0
|
||||
|
||||
def addNode(self, value):
|
||||
node = Node(value)
|
||||
if not self.head:
|
||||
self.head = node
|
||||
if self.tail:
|
||||
self.tail.next = node
|
||||
self.tail = node
|
||||
self.length += 1
|
||||
|
||||
def printList(self):
|
||||
node = self.head
|
||||
while node:
|
||||
print(node.value)
|
||||
node = node.next
|
||||
|
||||
def addInOrder(self, item):
|
||||
new_node = Node(item)
|
||||
node = self.head
|
||||
previous = None
|
||||
stop = False
|
||||
while node and not stop:
|
||||
if node.value > item:
|
||||
stop = True
|
||||
else:
|
||||
previous = node
|
||||
node = node.next
|
||||
|
||||
if not previous:
|
||||
new_node.next = self.head
|
||||
self.head = new_node
|
||||
else:
|
||||
new_node.next = node
|
||||
previous.next = new_node
|
||||
|
||||
|
||||
|
||||
def deleteNode(self, index):
|
||||
prev = None
|
||||
node = self.head
|
||||
i = 0
|
||||
while node and i < index:
|
||||
prev = node
|
||||
node = node.next
|
||||
i += 1
|
||||
if i == index:
|
||||
if not prev:
|
||||
self.head = node.next
|
||||
else:
|
||||
prev.next = node.next
|
||||
self.length -= 1
|
||||
else:
|
||||
print('Index not found!')
|
||||
|
||||
|
||||
def deleteNodeIfOrdered(self, item):
|
||||
node = self.head
|
||||
previous = None
|
||||
found = False
|
||||
while node and not found:
|
||||
if node.value == item:
|
||||
found = True
|
||||
else:
|
||||
previous = node
|
||||
node = node.next
|
||||
|
||||
if found:
|
||||
if not previous:
|
||||
self.head = node.next
|
||||
else:
|
||||
previous.next = node.next
|
||||
else:
|
||||
print('Node not found!')
|
||||
|
||||
|
||||
def removeDupl(self):
|
||||
prev = None
|
||||
node = self.head
|
||||
aux_dict = Counter()
|
||||
while node:
|
||||
value_here = node.value
|
||||
if aux_dict[value_here] == 0:
|
||||
aux_dict[value_here] = 1
|
||||
else:
|
||||
if prev == None:
|
||||
self.head = node.next
|
||||
else:
|
||||
prev.next = node.next
|
||||
self.length -= 1
|
||||
prev = node
|
||||
node = node.next
|
||||
|
||||
def removeDupl_no_buf(self):
|
||||
node = self.head
|
||||
while node:
|
||||
pivot = node.value
|
||||
pointer = node.next
|
||||
prev = node
|
||||
while pointer:
|
||||
value_here = pointer.value
|
||||
if value_here == pivot:
|
||||
prev.next = pointer.next
|
||||
self.length -= 1
|
||||
prev = pointer
|
||||
pointer = pointer.next
|
||||
node = node.next
|
||||
|
||||
def searchIfOrdered(self, item):
|
||||
node = self.head
|
||||
found = False
|
||||
stop = False
|
||||
while node and not found and not stop:
|
||||
if node.value == item:
|
||||
found = True
|
||||
else:
|
||||
if node.value > item:
|
||||
stop = True
|
||||
else:
|
||||
node = node.next
|
||||
return found
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
from collections import Counter
|
||||
|
||||
def main():
|
||||
|
||||
ll = LinkList()
|
||||
for i in range(1, 10):
|
||||
ll.addNode(i)
|
||||
ll.addNode(i+1)
|
||||
print('Linked List with duplicates:')
|
||||
ll.printList()
|
||||
print('Length before deleting duplicate is: ', ll.length)
|
||||
ll.removeDupl()
|
||||
ll.printList()
|
||||
print('Lenght after deleting duplicates is: ', ll.length)
|
||||
|
||||
ll = LinkList()
|
||||
for i in range(1, 10):
|
||||
ll.addNode(i)
|
||||
ll.addNode(i+1)
|
||||
print('Linked List with duplicates:')
|
||||
ll.printList()
|
||||
print('Length before deleting duplicate is: ', ll.length)
|
||||
ll.removeDupl_no_buf()
|
||||
ll.printList()
|
||||
print('Lenght after deleting duplicates is: ', ll.length)
|
||||
|
||||
|
||||
ll = LinkList()
|
||||
l1 = [4, 2, 5, 7, 1, 9]
|
||||
for i in l1:
|
||||
ll.addInOrder(i)
|
||||
ll.printList()
|
||||
print(ll.searchIfOrdered(7))
|
||||
print(ll.searchIfOrdered(3))
|
||||
ll.deleteNodeIfOrdered(7)
|
||||
ll.printList()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
82
src/further_examples/linked_list/linked_list_lifo.py
Normal file
82
src/further_examples/linked_list/linked_list_lifo.py
Normal file
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
''' Implement a unordered linked list, i.e. a LIFO linked list (like a stack) '''
|
||||
|
||||
class Node(object):
|
||||
def __init__(self, value = None, next = None):
|
||||
self.value = value
|
||||
self.next = next
|
||||
|
||||
class LinkList(object):
|
||||
def __init__(self):
|
||||
self.head = None
|
||||
self.lenght = 0
|
||||
|
||||
def addNode(self, value):
|
||||
node = Node(value)
|
||||
node.next = self.head
|
||||
self.head = node
|
||||
self.lenght += 1
|
||||
|
||||
def printList(self):
|
||||
node = self.head
|
||||
while node:
|
||||
print(node.value)
|
||||
node = node.next
|
||||
|
||||
def deleteNode(self, index):
|
||||
prev = None
|
||||
node = self.head
|
||||
i = 0
|
||||
while node and i < index:
|
||||
prev = node
|
||||
node = node.next
|
||||
i += 1
|
||||
if index == i:
|
||||
self.lenght -= 1
|
||||
if prev == None:
|
||||
self.head = node.next
|
||||
else:
|
||||
prev.next = node.next
|
||||
else:
|
||||
print('Node with index {} not found'.format(index))
|
||||
|
||||
|
||||
def deleteNodeByValue(self, item):
|
||||
prev = None
|
||||
node = self.head
|
||||
found = False
|
||||
while node and not found:
|
||||
if node.value == item:
|
||||
found = True
|
||||
else:
|
||||
prev = node
|
||||
node = node.next
|
||||
if found:
|
||||
self.lenght -= 1
|
||||
if prev == None:
|
||||
self.head = node.next
|
||||
else:
|
||||
prev.next = node.next
|
||||
else:
|
||||
print('Node with value {} not found'.format(item))
|
||||
|
||||
|
||||
def main():
|
||||
ll = LinkList()
|
||||
for i in range(1, 11):
|
||||
ll.addNode(i)
|
||||
print('The list is:')
|
||||
ll.printList()
|
||||
print('The list after deleting node with index 2 (value 8):')
|
||||
ll.deleteNode(2)
|
||||
ll.printList()
|
||||
print('The list after deleting node with value 2 (index 7):')
|
||||
ll.deleteNodeByValue(2)
|
||||
ll.printList()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
45
src/further_examples/linked_list/part_ll.py
Normal file
45
src/further_examples/linked_list/part_ll.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' This function partionate 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 LinkList, Node
|
||||
|
||||
def partList(ll, n):
|
||||
more = LinkList()
|
||||
less = LinkList()
|
||||
node_old = ll.head
|
||||
while node_old:
|
||||
item = node_old.value
|
||||
if item < n:
|
||||
less.addNode(item)
|
||||
elif item > n:
|
||||
more.addNode(item)
|
||||
node_old = node_old.next
|
||||
|
||||
less.addNode(n)
|
||||
nodemore = more.head
|
||||
while nodemore:
|
||||
less.addNode(nodemore.value)
|
||||
nodemore = nodemore.next
|
||||
return less
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
ll = LinkList()
|
||||
l1 = [6, 7, 3, 4, 9, 5, 1, 2, 8]
|
||||
for i in l1:
|
||||
ll.addNode(i)
|
||||
print('Before Part')
|
||||
ll.printList()
|
||||
print('After Part')
|
||||
newll = partList(ll, 6)
|
||||
newll.printList()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
70
src/further_examples/linked_list/sum_ll.py
Normal file
70
src/further_examples/linked_list/sum_ll.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' Supposing two linked lists represening 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 Node, LinkList
|
||||
|
||||
|
||||
def sumlls(l1, l2):
|
||||
lsum = LinkList()
|
||||
dig1 = l1.head
|
||||
dig2 = l2.head
|
||||
next = 0
|
||||
while dig1 and dig2:
|
||||
d1 = dig1.value
|
||||
d2 = dig2.value
|
||||
sum_d = d1 + d2 + next
|
||||
if sum_d > 9:
|
||||
next = sum_d//10
|
||||
lsum.addNode(sum_d%10)
|
||||
|
||||
else:
|
||||
lsum.addNode(sum_d)
|
||||
next = 0
|
||||
|
||||
dig1 = dig1.next
|
||||
dig2 = dig2.next
|
||||
|
||||
if dig1:
|
||||
sum_d = next + dig1.value
|
||||
if sum_d > 9:
|
||||
lsum.addNode(sum_d%10)
|
||||
else:
|
||||
lsum.addNode(sum_d)
|
||||
dig1 = dig1.next
|
||||
|
||||
if dig2:
|
||||
sum_d = next + dig2.value
|
||||
if sum_d > 9:
|
||||
lsum.addNode(sum_d%10)
|
||||
else:
|
||||
lsum.addNode(sum_d)
|
||||
dig2 = dig2.next
|
||||
|
||||
|
||||
return lsum
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
l1 = LinkList() # 2671
|
||||
l1.addNode(1)
|
||||
l1.addNode(7)
|
||||
l1.addNode(6)
|
||||
l1.addNode(2)
|
||||
|
||||
l2 = LinkList() # 455
|
||||
l2.addNode(5)
|
||||
l2.addNode(5)
|
||||
l2.addNode(4)
|
||||
|
||||
lsum = sumlls(l1, l2)
|
||||
lsum.printList()# 3126
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue