__init__.py
from .trees import BinaryTree, AVLTree, BinarySearchTree, BinHeap, BinaryTree
from .basic import Stack, Queue, Deque
from .graphs import Graph, Vertex, PriorityQueue
__ALL__ = [Stack, Queue, Deque, Graph, Vertex, PriorityQueue, BinaryTree, AVLTree, BinarySearchTree, BinHeap, BinaryTree]
basic
- __init__.py
#__all__ = ["stack"]
from .stack import Stack
from .queue import Queue
from .deque import Deque
- deque.py
#deque.py
class Deque:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def addFront(self, item):
self.items.append(item)
def addRear(self, item):
self.items.insert(0,item)
def removeFront(self):
return self.items.pop()
def removeRear(self):
return self.items.pop(0)
def size(self):
return len(self.items)
- queue.py
# Bradley N. Miller, David L. Ranum
# Introduction to Data Structures and Algorithms in Python
# Copyright 2005
#
#queue.py
class Queue:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0,item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
- stack.py
# Bradley N. Miller, David L. Ranum
# Introduction to Data Structures and Algorithms in Python
# Copyright 2005
#
#stack.py
class Stack:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
trees
- __init__.py
from .balance import AVLTree
from .bst import BinarySearchTree
from .binheap import BinHeap
from .binaryTree import BinaryTree
- balance.py
#!/bin/env python3.1
import unittest
from .bst import BinarySearchTree, TreeNode
class AVLTree(BinarySearchTree):
'''
Author: Brad Miller
Date: 1/15/2005
Description: Imlement a binary search tree with the following interface
functions:
__contains__(y) <==> y in x
__getitem__(y) <==> x[y]
__init__()
__len__() <==> len(x)
__setitem__(k,v) <==> x[k] = v
clear()
get(k)
has_key(k)
items()
keys()
values()
put(k,v)
'''
def _put(self,key,val,currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key,val,currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key,val,parent=currentNode)
self.updateBalance(currentNode.leftChild)
else:
if currentNode.hasRightChild():
self._put(key,val,currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key,val,parent=currentNode)
self.updateBalance(currentNode.rightChild)
def updateBalance(self,node):
if node.balanceFactor > 1 or node.balanceFactor < -1:
self.rebalance(node)
return
if node.parent != None:
if node.isLeftChild():
node.parent.balanceFactor += 1
elif node.isRightChild():
node.parent.balanceFactor -= 1
if node.parent.balanceFactor != 0:
self.updateBalance(node.parent)
def rebalance(self,node):
if node.balanceFactor < 0:
if node.rightChild.balanceFactor > 0:
# Do an LR Rotation
self.rotateRight(node.rightChild)
self.rotateLeft(node)
else:
# single left
self.rotateLeft(node)
elif node.balanceFactor > 0:
if node.leftChild.balanceFactor < 0:
# Do an RL Rotation
self.rotateLeft(node.leftChild)
self.rotateRight(node)
else:
# single right
self.rotateRight(node)
def rotateLeft(self,rotRoot):
newRoot = rotRoot.rightChild
rotRoot.rightChild = newRoot.leftChild
if newRoot.leftChild != None:
newRoot.leftChild.parent = rotRoot
newRoot.parent = rotRoot.parent
if rotRoot.isRoot():
self.root = newRoot
else:
if rotRoot.isLeftChild():
rotRoot.parent.leftChild = newRoot
else:
rotRoot.parent.rightChild = newRoot
newRoot.leftChild = rotRoot
rotRoot.parent = newRoot
rotRoot.balanceFactor = rotRoot.balanceFactor + 1 - min(newRoot.balanceFactor, 0)
newRoot.balanceFactor = newRoot.balanceFactor + 1 + max(rotRoot.balanceFactor, 0)
def rotateRight(self,rotRoot):
newRoot = rotRoot.leftChild
rotRoot.leftChild = newRoot.rightChild
if newRoot.rightChild != None:
newRoot.rightChild.parent = rotRoot
newRoot.parent = rotRoot.parent
if rotRoot.isRoot():
self.root = newRoot
else:
if rotRoot.isRightChild():
rotRoot.parent.rightChild = newRoot
else:
rotRoot.parent.leftChild = newRoot
newRoot.rightChild = rotRoot
rotRoot.parent = newRoot
rotRoot.balanceFactor = rotRoot.balanceFactor - 1 - max(newRoot.balanceFactor, 0)
newRoot.balanceFactor = newRoot.balanceFactor - 1 + min(rotRoot.balanceFactor, 0)
class BinaryTreeTests(unittest.TestCase):
def setUp(self):
self.bst = AVLTree()
def testAuto1(self):
self.bst.put(30,'a')
self.bst.put(50,'b')
self.bst.put(40,'c')
assert self.bst.root.key == 40
def testAuto2(self):
self.bst.put(50,'a')
self.bst.put(30,'b')
self.bst.put(40,'c')
assert self.bst.root.key == 40
def testAuto3(self):
self.bst.put(50,'a')
self.bst.put(30,'b')
self.bst.put(70,'c')
self.bst.put(80,'c')
self.bst.put(60,'d')
self.bst.put(90,'e')
assert self.bst.root.key == 70
def testAuto3(self):
self.bst.put(40,'a')
self.bst.put(30,'b')
self.bst.put(50,'c')
self.bst.put(45,'d')
self.bst.put(60,'e')
self.bst.put(43,'f')
assert self.bst.root.key == 45
assert self.bst.root.leftChild.key == 40
assert self.bst.root.rightChild.key == 50
assert self.bst.root.balanceFactor == 0
assert self.bst.root.leftChild.balanceFactor == 0
assert self.bst.root.rightChild.balanceFactor == -1
def testAuto4(self):
self.bst.put(40,'a')
self.bst.put(30,'b')
self.bst.put(50,'c')
self.bst.put(10,'d')
self.bst.put(35,'e')
self.bst.put(37,'f')
assert self.bst.root.key == 35
assert self.bst.root.leftChild.key == 30
assert self.bst.root.rightChild.key == 40
assert self.bst.root.balanceFactor == 0
assert self.bst.root.leftChild.balanceFactor == 1
assert self.bst.root.rightChild.balanceFactor == 0
if __name__ == '__main__':
import platform
print(platform.python_version())
unittest.main()
# Local Variables:
# py-which-shell: "python3"
# End:
- binaryTree.py
from __future__ import print_function
class BinaryTree:
"""
A recursive implementation of Binary Tree
Using links and Nodes approach.
Modified to allow for trees to be constructed from other trees rather than always creating
a new tree in the insertLeft or insertRight
"""
def __init__(self,rootObj):
self.key = rootObj
self.leftChild = None
self.rightChild = None
def insertLeft(self,newNode):
if isinstance(newNode, BinaryTree):
t = newNode
else:
t = BinaryTree(newNode)
if self.leftChild is not None:
t.left = self.leftChild
self.leftChild = t
def insertRight(self,newNode):
if isinstance(newNode,BinaryTree):
t = newNode
else:
t = BinaryTree(newNode)
if self.rightChild is not None:
t.right = self.rightChild
self.rightChild = t
def isLeaf(self):
return ((not self.leftChild) and (not self.rightChild))
def getRightChild(self):
return self.rightChild
def getLeftChild(self):
return self.leftChild
def setRootVal(self,obj):
self.key = obj
def getRootVal(self,):
return self.key
def inorder(self):
if self.leftChild:
self.leftChild.inorder()
print(self.key)
if self.rightChild:
self.rightChild.inorder()
def postorder(self):
if self.leftChild:
self.leftChild.postorder()
if self.rightChild:
self.rightChild.postorder()
print(self.key)
def preorder(self):
print(self.key)
if self.leftChild:
self.leftChild.preorder()
if self.rightChild:
self.rightChild.preorder()
def printexp(self):
if self.leftChild:
print('(', end=' ')
self.leftChild.printexp()
print(self.key, end=' ')
if self.rightChild:
self.rightChild.printexp()
print(')', end=' ')
def postordereval(self):
opers = {'+':operator.add, '-':operator.sub, '*':operator.mul, '/':operator.truediv}
res1 = None
res2 = None
if self.leftChild:
res1 = self.leftChild.postordereval() #// \label{peleft}
if self.rightChild:
res2 = self.rightChild.postordereval() #// \label{peright}
if res1 and res2:
return opers[self.key](res1,res2) #// \label{peeval}
else:
return self.key
def inorder(tree):
if tree != None:
inorder(tree.getLeftChild())
print(tree.getRootVal())
inorder(tree.getRightChild())
def printexp(tree):
if tree.leftChild:
print('(', end=' ')
printexp(tree.getLeftChild())
print(tree.getRootVal(), end=' ')
if tree.rightChild:
printexp(tree.getRightChild())
print(')', end=' ')
def printexp(tree):
sVal = ""
if tree:
sVal = '(' + printexp(tree.getLeftChild())
sVal = sVal + str(tree.getRootVal())
sVal = sVal + printexp(tree.getRightChild()) + ')'
return sVal
def postordereval(tree):
opers = {'+':operator.add, '-':operator.sub, '*':operator.mul, '/':operator.truediv}
res1 = None
res2 = None
if tree:
res1 = postordereval(tree.getLeftChild()) #// \label{peleft}
res2 = postordereval(tree.getRightChild()) #// \label{peright}
if res1 and res2:
return opers[tree.getRootVal()](res1,res2) #// \label{peeval}
else:
return tree.getRootVal()
def height(tree):
if tree == None:
return -1
else:
return 1 + max(height(tree.leftChild),height(tree.rightChild))
if __name__ == '__main__':
t = BinaryTree(7)
t.insertLeft(3)
t.insertRight(9)
inorder(t)
import operator
x = BinaryTree('*')
x.insertLeft('+')
l = x.getLeftChild()
l.insertLeft(4)
l.insertRight(5)
x.insertRight(7)
print(printexp(x))
print(postordereval(x))
print(height(x))
- binheap.py
import unittest
# this heap takes key value pairs, we will assume that the keys are integers
class BinHeap:
def __init__(self):
self.heapList = [0]
self.currentSize = 0
def buildHeap(self,alist):
i = len(alist) // 2
self.currentSize = len(alist)
self.heapList = [0] + alist[:]
print(len(self.heapList), i)
while (i > 0):
print(self.heapList, i)
self.percDown(i)
i = i - 1
print(self.heapList,i)
def percDown(self,i):
while (i * 2) <= self.currentSize:
mc = self.minChild(i)
if self.heapList[i] > self.heapList[mc]:
tmp = self.heapList[i]
self.heapList[i] = self.heapList[mc]
self.heapList[mc] = tmp
i = mc
def minChild(self,i):
if i * 2 + 1 > self.currentSize:
return i * 2
else:
if self.heapList[i * 2] < self.heapList[i * 2 + 1]:
return i * 2
else:
return i * 2 + 1
def percUp(self,i):
while i // 2 > 0:
if self.heapList[i] < self.heapList[i//2]:
tmp = self.heapList[i // 2]
self.heapList[i // 2] = self.heapList[i]
self.heapList[i] = tmp
i = i // 2
def insert(self,k):
self.heapList.append(k)
self.currentSize = self.currentSize + 1
self.percUp(self.currentSize)
def delMin(self):
retval = self.heapList[1]
self.heapList[1] = self.heapList[self.currentSize]
self.currentSize = self.currentSize - 1
self.heapList.pop()
self.percDown(1)
return retval
def isEmpty(self):
if currentSize == 0:
return True
else:
return False
class FooThing:
def __init__(self,x,y):
self.key = x
self.val = y
def __lt__(self,other):
if self.key < other.key:
return True
else:
return False
def __gt__(self,other):
if self.key > other.key:
return True
else:
return False
def __hash__(self):
return self.key
class TestBinHeap(unittest.TestCase):
def setUp(self):
self.theHeap = BinHeap()
self.theHeap.insert(FooThing(5,'a'))
self.theHeap.insert(FooThing(9,'d'))
self.theHeap.insert(FooThing(1,'x'))
self.theHeap.insert(FooThing(2,'y'))
self.theHeap.insert(FooThing(3,'z'))
def testInsert(self):
assert self.theHeap.currentSize == 5
def testDelmin(self):
assert self.theHeap.delMin().val == 'x'
assert self.theHeap.delMin().val == 'y'
assert self.theHeap.delMin().val == 'z'
assert self.theHeap.delMin().val == 'a'
def testMixed(self):
myHeap = BinHeap()
myHeap.insert(9)
myHeap.insert(1)
myHeap.insert(5)
assert myHeap.delMin() == 1
myHeap.insert(2)
myHeap.insert(7)
assert myHeap.delMin() == 2
assert myHeap.delMin() == 5
def testDupes(self):
myHeap = BinHeap()
myHeap.insert(9)
myHeap.insert(1)
myHeap.insert(8)
myHeap.insert(1)
assert myHeap.currentSize == 4
assert myHeap.delMin() == 1
assert myHeap.delMin() == 1
assert myHeap.delMin() == 8
def testBuildHeap(self):
myHeap = BinHeap()
myHeap.buildHeap([9,5,6,2,3])
f = myHeap.delMin()
print("f = ", f)
assert f == 2
assert myHeap.delMin() == 3
assert myHeap.delMin() == 5
assert myHeap.delMin() == 6
assert myHeap.delMin() == 9
if __name__ == '__main__':
d = {}
d[FooThing(1,'z')] = 10
unittest.main()
- bst.py
#!/bin/env python3.1
import unittest
class BinarySearchTree:
'''
Author: Brad Miller
Date: 1/15/2005
Description: Imlement a binary search tree with the following interface
functions:
__contains__(y) <==> y in x
__getitem__(y) <==> x[y]
__init__()
__len__() <==> len(x)
__setitem__(k,v) <==> x[k] = v
clear()
get(k)
items()
keys()
values()
put(k,v)
in
del <==>
'''
def __init__(self):
self.root = None
self.size = 0
def put(self,key,val):
if self.root:
self._put(key,val,self.root)
else:
self.root = TreeNode(key,val)
self.size = self.size + 1
def _put(self,key,val,currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key,val,currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key,val,parent=currentNode)
else:
if currentNode.hasRightChild():
self._put(key,val,currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key,val,parent=currentNode)
def __setitem__(self,k,v):
self.put(k,v)
def get(self,key):
if self.root:
res = self._get(key,self.root)
if res:
return res.payload
else:
return None
else:
return None
def _get(self,key,currentNode):
if not currentNode:
return None
elif currentNode.key == key:
return currentNode
elif key < currentNode.key:
return self._get(key,currentNode.leftChild)
else:
return self._get(key,currentNode.rightChild)
def __getitem__(self,key):
res = self.get(key)
if res:
return res
else:
raise KeyError('Error, key not in tree')
def __contains__(self,key):
if self._get(key,self.root):
return True
else:
return False
def length(self):
return self.size
def __len__(self):
return self.size
def __iter__(self):
return self.root.__iter__()
def delete(self,key):
if self.size > 1:
nodeToRemove = self._get(key,self.root)
if nodeToRemove:
self.remove(nodeToRemove)
self.size = self.size-1
else:
raise KeyError('Error, key not in tree')
elif self.size == 1 and self.root.key == key:
self.root = None
self.size = self.size - 1
else:
raise KeyError('Error, key not in tree')
def __delitem__(self,key):
self.delete(key)
def remove(self,currentNode):
if currentNode.isLeaf(): #leaf
if currentNode == currentNode.parent.leftChild:
currentNode.parent.leftChild = None
else:
currentNode.parent.rightChild = None
elif currentNode.hasBothChildren(): #interior
succ = currentNode.findSuccessor()
succ.spliceOut()
currentNode.key = succ.key
currentNode.payload = succ.payload
else: # this node has one child
if currentNode.hasLeftChild():
if currentNode.isLeftChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.leftChild
elif currentNode.isRightChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.leftChild
else:
currentNode.replaceNodeData(currentNode.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
else:
if currentNode.isLeftChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.rightChild
elif currentNode.isRightChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.rightChild
else:
currentNode.replaceNodeData(currentNode.rightChild.key,
currentNode.rightChild.payload,
currentNode.rightChild.leftChild,
currentNode.rightChild.rightChild)
def inorder(self):
self._inorder(self.root)
def _inorder(self,tree):
if tree != None:
self._inorder(tree.leftChild)
print(tree.key)
self._inorder(tree.rightChild)
def postorder(self):
self._postorder(self.root)
def _postorder(self, tree):
if tree:
self._postorder(tree.rightChild)
self._postorder(tree.leftChild)
print(tree.key)
def preorder(self):
self._preorder(self,self.root)
def _preorder(self,tree):
if tree:
print(tree.key)
self._preorder(tree.leftChild)
self._preorder(tree.rightChild)
class TreeNode:
def __init__(self,key,val,left=None,right=None,parent=None):
self.key = key
self.payload = val
self.leftChild = left
self.rightChild = right
self.parent = parent
self.balanceFactor = 0
def hasLeftChild(self):
return self.leftChild
def hasRightChild(self):
return self.rightChild
def isLeftChild(self):
return self.parent and self.parent.leftChild == self
def isRightChild(self):
return self.parent and self.parent.rightChild == self
def isRoot(self):
return not self.parent
def isLeaf(self):
return not (self.rightChild or self.leftChild)
def hasAnyChildren(self):
return self.rightChild or self.leftChild
def hasBothChildren(self):
return self.rightChild and self.leftChild
def replaceNodeData(self,key,value,lc,rc):
self.key = key
self.payload = value
self.leftChild = lc
self.rightChild = rc
if self.hasLeftChild():
self.leftChild.parent = self
if self.hasRightChild():
self.rightChild.parent = self
def findSuccessor(self):
succ = None
if self.hasRightChild():
succ = self.rightChild.findMin()
else:
if self.parent:
if self.isLeftChild():
succ = self.parent
else:
self.parent.rightChild = None
succ = self.parent.findSuccessor()
self.parent.rightChild = self
return succ
def spliceOut(self):
if self.isLeaf():
if self.isLeftChild():
self.parent.leftChild = None
else:
self.parent.rightChild = None
elif self.hasAnyChildren():
if self.hasLeftChild():
if self.isLeftChild():
self.parent.leftChild = self.leftChild
else:
self.parent.rightChild = self.leftChild
self.leftChild.parent = self.parent
else:
if self.isLeftChild():
self.parent.leftChild = self.rightChild
else:
self.parent.rightChild = self.rightChild
self.rightChild.parent = self.parent
def findMin(self):
current = self
while current.hasLeftChild():
current = current.leftChild
return current
def __iter__(self):
"""The standard inorder traversal of a binary tree."""
if self:
if self.hasLeftChild():
for elem in self.leftChild:
yield elem
yield self.key
if self.hasRightChild():
for elem in self.rightChild:
yield elem
class BinaryTreeTests(unittest.TestCase):
def setUp(self):
self.bst = BinarySearchTree()
def testgetput(self):
print('testgetput')
self.bst.put(50,'a')
self.bst.put(10,'b')
self.bst.put(70,'c')
self.bst.put(30,'d')
self.bst.put(85,'d')
self.bst.put(15,'e')
self.bst.put(45,'f')
print(self.bst.get(50))
assert self.bst.get(50) == 'a'
assert self.bst.get(45) == 'f'
assert self.bst.get(85) == 'd'
assert self.bst.get(10) == 'b'
assert self.bst.root.key == 50
assert self.bst.root.leftChild.key == 10
assert self.bst.root.rightChild.key == 70
def testputoper(self):
print('testputoper')
self.bst[25] = 'g'
assert self.bst[25] == 'g'
def testFindSucc(self):
print('testing findSucc')
x = BinarySearchTree()
x.put(10,'a')
x.put(15,'b')
x.put(6,'c')
x.put(2,'d')
x.put(8,'e')
x.put(9,'f')
assert x.root.leftChild.leftChild.findSuccessor().key == 6
assert x.root.leftChild.rightChild.findSuccessor().key == 9
assert x.root.leftChild.rightChild.rightChild.findSuccessor().key == 10
def testSize(self):
print('testing testSize')
self.bst.put(50,'a')
self.bst.put(10,'b')
self.bst.put(70,'c')
self.bst.put(30,'d')
self.bst.put(85,'d')
self.bst.put(15,'e')
self.bst.put(45,'f')
assert self.bst.length() == 7
def testDelete(self):
print('testing delete')
self.bst.put(50,'a')
self.bst.put(10,'b')
self.bst.put(70,'c')
self.bst.put(30,'d')
self.bst.put(85,'d')
self.bst.put(15,'e')
self.bst.put(45,'f')
self.bst.put(5,'g')
print('initial inorder')
self.bst.inorder()
assert (10 in self.bst) == True
self.bst.delete_key(10)
print('delete 10 inorder')
self.bst.inorder()
assert (10 in self.bst) == False
assert self.bst.root.leftChild.key == 15
assert self.bst.root.leftChild.parent == self.bst.root
assert self.bst.root.leftChild.rightChild.parent == self.bst.root.leftChild
assert self.bst.get(30) == 'd'
self.bst.delete_key(15)
print('delete 15 inorder')
self.bst.inorder()
assert self.bst.root.leftChild.key == 30
assert self.bst.root.leftChild.rightChild.key == 45
assert self.bst.root.leftChild.rightChild.parent == self.bst.root.leftChild
self.bst.delete_key(70)
print('delete 70 inorder')
self.bst.inorder()
assert (85 in self.bst) == True
assert self.bst.get(30) == 'd'
print('root key = ', self.bst.root.key)
print('left = ',self.bst.root.leftChild.key)
print('left left = ',self.bst.root.leftChild.leftChild.key)
print('left right = ',self.bst.root.leftChild.rightChild.key)
print('right = ',self.bst.root.rightChild.key)
self.bst.delete_key(50)
assert self.bst.root.key == 85
assert self.bst.root.leftChild.key == 30
assert self.bst.root.rightChild == None
assert self.bst.root.leftChild.leftChild.key == 5
assert self.bst.root.leftChild.rightChild.key == 45
assert self.bst.root.leftChild.leftChild.parent == self.bst.root.leftChild
assert self.bst.root.leftChild.rightChild.parent == self.bst.root.leftChild
print('new root key = ', self.bst.root.key)
self.bst.inorder()
self.bst.delete_key(45)
assert self.bst.root.leftChild.key == 30
self.bst.delete_key(85)
assert self.bst.root.key == 30
print('xxxx ',self.bst.root.leftChild.parent.key, self.bst.root.key)
assert self.bst.root.leftChild.parent == self.bst.root
self.bst.delete_key(30)
assert self.bst.root.key == 5
self.bst.inorder()
print("final root = " + str(self.bst.root.key))
assert self.bst.root.key == 5
self.bst.delete_key(5)
assert self.bst.root == None
def testDel2(self):
self.bst.put(21,'a')
self.bst.put(10,'b')
self.bst.put(24,'c')
self.bst.put(11,'d')
self.bst.put(22,'d')
self.bst.delete_key(10)
assert self.bst.root.leftChild.key == 11
assert self.bst.root.leftChild.parent == self.bst.root
assert self.bst.root.rightChild.key == 24
self.bst.delete_key(24)
assert self.bst.root.rightChild.key == 22
assert self.bst.root.rightChild.parent == self.bst.root
self.bst.delete_key(22)
self.bst.delete_key(21)
print("del2 root = ",self.bst.root.key)
assert self.bst.root.key == 11
assert self.bst.root.leftChild == None
assert self.bst.root.rightChild == None
def testLarge(self):
import random
print('testing a large random tree')
i = 0
randList = []
while i < 10000:
nrand = random.randrange(1,10000000)
if nrand not in randList:
randList.append(nrand)
i += 1
print(randList)
for n in randList:
self.bst.put(n,n)
sortList = randList[:]
sortList.sort()
random.shuffle(randList)
for n in randList:
minNode = self.bst.root.findMin()
if minNode:
assert minNode.key == sortList[0]
rootPos = sortList.index(self.bst.root.key)
succ = self.bst.root.findSuccessor()
if succ:
assert succ.key == sortList[rootPos+1]
else:
assert self.bst.root.rightChild == None
self.bst.delete_key(n)
sortList.remove(n)
assert self.bst.root == None
def testIter(self):
import random
i = 0
randList = []
while i < 100:
nrand = random.randrange(1,10000)
if nrand not in randList:
randList.append(nrand)
i += 1
for n in randList:
self.bst.put(n,n)
sortList = randList[:]
sortList.sort()
i = 0
for j in self.bst:
assert j == sortList[i]
i += 1
# the following exercises all of the branches in deleting a node with one child
def testCase1(self):
self.bst.put(10,10)
self.bst.put(7,7)
self.bst.put(5,5)
self.bst.put(1,1)
self.bst.put(6,6)
self.bst.delete_key(7)
assert self.bst.root.leftChild.key == 5
assert self.bst.root == self.bst.root.leftChild.parent
assert self.bst.root.leftChild.leftChild.key == 1
assert self.bst.root.leftChild.rightChild.key == 6
def testCase2(self):
self.bst = BinarySearchTree()
self.bst.put(10,10)
self.bst.put(15,15)
self.bst.put(12,12)
self.bst.put(11,11)
self.bst.put(13,13)
self.bst.delete_key(15)
assert self.bst.root.rightChild.key == 12
assert self.bst.root.rightChild.parent == self.bst.root
assert self.bst.root.rightChild.leftChild.key == 11
assert self.bst.root.rightChild.rightChild.key == 13
def testCase3(self):
self.bst = BinarySearchTree()
self.bst.put(10,10)
self.bst.put(6,6)
self.bst.put(8,8)
self.bst.put(7,7)
self.bst.put(9,9)
self.bst.delete_key(6)
assert self.bst.root.leftChild.key == 8
assert self.bst.root.leftChild.parent == self.bst.root
assert self.bst.root.leftChild.leftChild.key == 7
assert self.bst.root.leftChild.rightChild.key == 9
def testCase4(self):
self.bst = BinarySearchTree()
self.bst.put(10,10)
self.bst.put(15,15)
self.bst.put(20,20)
self.bst.put(17,17)
self.bst.put(22,22)
self.bst.delete_key(15)
assert self.bst.root.rightChild.key == 20
assert self.bst.root.rightChild.parent == self.bst.root
assert self.bst.root.rightChild.rightChild.key == 22
assert self.bst.root.rightChild.leftChild.key == 17
def testCase5(self):
self.bst.put(10,10)
self.bst.put(20,20)
self.bst.put(17,17)
self.bst.put(22,22)
self.bst.delete_key(10)
assert self.bst.root.key == 20
assert self.bst.root.leftChild.parent == self.bst.root
assert self.bst.root.rightChild.parent == self.bst.root
assert self.bst.root.leftChild.key == 17
assert self.bst.root.rightChild.key == 22
def testCase6(self):
self.bst.put(10,10)
self.bst.put(5,5)
self.bst.put(1,1)
self.bst.put(7,7)
self.bst.delete_key(10)
assert self.bst.root.key == 5
assert self.bst.root.leftChild.parent == self.bst.root
assert self.bst.root.rightChild.parent == self.bst.root
assert self.bst.root.leftChild.key == 1
assert self.bst.root.rightChild.key == 7
def testBadDelete(self):
self.bst.put(10,10)
with self.assertRaises(KeyError):
self.bst.delete_key(5)
self.bst.delete_key(10)
with self.assertRaises(KeyError):
self.bst.delete_key(5)
if __name__ == '__main__':
import platform
print(platform.python_version())
unittest.main()
### Local Variables:
### End:
graphs
- __init__.py
from .adjGraph import Graph
from .adjGraph import Vertex
from .priorityQueue import PriorityQueue
- adjGraph.py
# adjGraph
import sys
import os
import unittest
class Graph:
def __init__(self):
self.vertices = {}
self.numVertices = 0
def addVertex(self,key):
self.numVertices = self.numVertices + 1
newVertex = Vertex(key)
self.vertices[key] = newVertex
return newVertex
def getVertex(self,n):
if n in self.vertices:
return self.vertices[n]
else:
return None
def __contains__(self,n):
return n in self.vertices
def addEdge(self,f,t,cost=0):
if f not in self.vertices:
nv = self.addVertex(f)
if t not in self.vertices:
nv = self.addVertex(t)
self.vertices[f].addNeighbor(self.vertices[t],cost)
def getVertices(self):
return list(self.vertices.keys())
def __iter__(self):
return iter(self.vertices.values())
class Vertex:
def __init__(self,num):
self.id = num
self.connectedTo = {}
self.color = 'white'
self.dist = sys.maxsize
self.pred = None
self.disc = 0
self.fin = 0
# def __lt__(self,o):
# return self.id < o.id
def addNeighbor(self,nbr,weight=0):
self.connectedTo[nbr] = weight
def setColor(self,color):
self.color = color
def setDistance(self,d):
self.dist = d
def setPred(self,p):
self.pred = p
def setDiscovery(self,dtime):
self.disc = dtime
def setFinish(self,ftime):
self.fin = ftime
def getFinish(self):
return self.fin
def getDiscovery(self):
return self.disc
def getPred(self):
return self.pred
def getDistance(self):
return self.dist
def getColor(self):
return self.color
def getConnections(self):
return self.connectedTo.keys()
def getWeight(self,nbr):
return self.connectedTo[nbr]
def __str__(self):
return str(self.id) + ":color " + self.color + ":disc " + str(self.disc) + ":fin " + str(self.fin) + ":dist " + str(self.dist) + ":pred \n\t[" + str(self.pred)+ "]\n"
def getId(self):
return self.id
class adjGraphTests(unittest.TestCase):
def setUp(self):
self.tGraph = Graph()
def testMakeGraph(self):
gFile = open("test.dat")
for line in gFile:
fVertex, tVertex = line.split('|')
fVertex = int(fVertex)
tVertex = int(tVertex)
self.tGraph.addEdge(fVertex,tVertex)
for i in self.tGraph:
adj = i.getAdj()
for k in adj:
print(i, k)
if __name__ == '__main__':
unittest.main()
- priorityQueue.py
# Introduction to Data Structures and Algorithms in Python
import unittest
# this implementation of binary heap takes key value pairs,
# we will assume that the keys are all comparable
class PriorityQueue:
def __init__(self):
self.heapArray = [(0,0)]
self.currentSize = 0
def buildHeap(self,alist):
self.currentSize = len(alist)
self.heapArray = [(0,0)]
for i in alist:
self.heapArray.append(i)
i = len(alist) // 2
while (i > 0):
self.percDown(i)
i = i - 1
def percDown(self,i):
while (i * 2) <= self.currentSize:
mc = self.minChild(i)
if self.heapArray[i][0] > self.heapArray[mc][0]:
tmp = self.heapArray[i]
self.heapArray[i] = self.heapArray[mc]
self.heapArray[mc] = tmp
i = mc
def minChild(self,i):
if i*2 > self.currentSize:
return -1
else:
if i*2 + 1 > self.currentSize:
return i*2
else:
if self.heapArray[i*2][0] < self.heapArray[i*2+1][0]:
return i*2
else:
return i*2+1
def percUp(self,i):
while i // 2 > 0:
if self.heapArray[i][0] < self.heapArray[i//2][0]:
tmp = self.heapArray[i//2]
self.heapArray[i//2] = self.heapArray[i]
self.heapArray[i] = tmp
i = i//2
def add(self,k):
self.heapArray.append(k)
self.currentSize = self.currentSize + 1
self.percUp(self.currentSize)
def delMin(self):
retval = self.heapArray[1][1]
self.heapArray[1] = self.heapArray[self.currentSize]
self.currentSize = self.currentSize - 1
self.heapArray.pop()
self.percDown(1)
return retval
def isEmpty(self):
if self.currentSize == 0:
return True
else:
return False
def decreaseKey(self,val,amt):
# this is a little wierd, but we need to find the heap thing to decrease by
# looking at its value
done = False
i = 1
myKey = 0
while not done and i <= self.currentSize:
if self.heapArray[i][1] == val:
done = True
myKey = i
else:
i = i + 1
if myKey > 0:
self.heapArray[myKey] = (amt,self.heapArray[myKey][1])
self.percUp(myKey)
def __contains__(self,vtx):
for pair in self.heapArray:
if pair[1] == vtx:
return True
return False
class TestBinHeap(unittest.TestCase):
def setUp(self):
self.theHeap = PriorityQueue()
self.theHeap.add((2,'x'))
self.theHeap.add((3,'y'))
self.theHeap.add((5,'z'))
self.theHeap.add((6,'a'))
self.theHeap.add((4,'d'))
def testInsert(self):
assert self.theHeap.currentSize == 5
def testDelmin(self):
assert self.theHeap.delMin() == 'x'
assert self.theHeap.delMin() == 'y'
def testDecKey(self):
self.theHeap.decreaseKey('d',1)
assert self.theHeap.delMin() == 'd'
if __name__ == '__main__':
unittest.main()