This commit is contained in:
Marina Wahl 2014-04-16 21:23:49 -04:00
parent 1e9fdfbbfd
commit 5107f16df0
96 changed files with 17 additions and 1702 deletions

View 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()

View 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()

View 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()

View 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()

View 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()

View 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()

View 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()

View 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()

View 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()