216 lines
4.0 KiB
Python
216 lines
4.0 KiB
Python
# Basisklasse fuer Baumstruktur
|
|
# Object-orientiertes Programmieren Wi/97
|
|
#
|
|
# (c) Martin Strubel, Fakultaet fuer Physik, Universitaet Konstanz
|
|
# (strubi@gandalf.physik.uni-konstanz.de)
|
|
|
|
# updated 08.2001
|
|
|
|
"""Simple binary tree module
|
|
|
|
This module demonstrates a binary tree class.
|
|
|
|
Example::
|
|
|
|
a = [5, 8, 8, 3, 7, 9]
|
|
t1 = Tree()
|
|
t1.fromList(a)
|
|
|
|
Operations on tree nodes are done by writing a simple operator class::
|
|
|
|
class myOp:
|
|
def __init__(self):
|
|
...
|
|
def operate(self, node):
|
|
do_something(node)
|
|
|
|
and calling the recursive application::
|
|
|
|
op = MyOp()
|
|
t1.recurse(op)
|
|
|
|
Objects inserted into the tree can be of any kind, as long as they define a
|
|
comparison operation.
|
|
"""
|
|
|
|
def recurse(node, do):
|
|
if node == None:
|
|
return
|
|
recurse(node.left, do)
|
|
do(node)
|
|
recurse(node.right, do)
|
|
|
|
class Nullnode:
|
|
def __init__(self):
|
|
self.left = None
|
|
self.right = None
|
|
self.depth = 0
|
|
|
|
def recurse(self, do):
|
|
if self == Nil:
|
|
return
|
|
self.left.recurse(do)
|
|
do(self)
|
|
self.right.recurse(do)
|
|
|
|
Nil = Nullnode()
|
|
|
|
def nothing(x):
|
|
return x
|
|
|
|
class Node(Nullnode):
|
|
def __init__(self, data = None):
|
|
self.left = Nil
|
|
self.right = Nil
|
|
self.data = data
|
|
self.depth = 0
|
|
|
|
def __repr__(self):
|
|
return "Node: %s" % self.data
|
|
|
|
def insert(self, node):
|
|
if node.data < self.data:
|
|
if self.left != Nil:
|
|
return self.left.insert(node)
|
|
else:
|
|
node.depth = self.depth + 1
|
|
self.left = node
|
|
# print "inserted left"
|
|
return self
|
|
|
|
elif node.data > self.data:
|
|
if self.right != Nil:
|
|
return self.right.insert(node)
|
|
else:
|
|
node.depth = self.depth + 1
|
|
self.right = node
|
|
# print "inserted right"
|
|
return self
|
|
else:
|
|
return self.insert_equal(node)
|
|
|
|
def find(self, node, do = nothing):
|
|
if node.data < self.data:
|
|
if self.left != Nil:
|
|
return self.left.find(node, do)
|
|
else:
|
|
return self
|
|
elif node.data > self.data:
|
|
if self.right != Nil:
|
|
return self.right.find(node, do)
|
|
else:
|
|
return self
|
|
else:
|
|
return do(self)
|
|
|
|
def remove(self, node):
|
|
newpar
|
|
return self
|
|
def insert_equal(self, node):
|
|
#print "insert:",
|
|
self.equal(node)
|
|
return self
|
|
def found_equal(self, node):
|
|
self.equal(node)
|
|
def equal(self, node):
|
|
# handle special
|
|
print "node (%s) is equal self (%s)" % (node, self)
|
|
def copy(self):
|
|
n = Node(self.data)
|
|
return n
|
|
|
|
def recursecopy(self):
|
|
n = Node()
|
|
n.data = self.data
|
|
n.flag = self.flag
|
|
if self.left != Nil:
|
|
n.left = self.left.recursecopy()
|
|
if self.right != Nil:
|
|
n.right = self.right.recursecopy()
|
|
|
|
return n
|
|
|
|
class NodeOp:
|
|
def __init__(self):
|
|
self.list = []
|
|
def copy(self, node):
|
|
self.list.append(node.data)
|
|
|
|
class Tree:
|
|
def __init__(self, root = None):
|
|
self.root = root
|
|
self.n = 0
|
|
def __radd__(self, other):
|
|
print other
|
|
t = self.copy()
|
|
t.merge(other)
|
|
return t
|
|
def __repr__(self):
|
|
return "Tree with %d elements" % self.n
|
|
def insert(self, node):
|
|
if self.root == None:
|
|
self.root = node
|
|
else:
|
|
self.root.insert(node)
|
|
self.n += 1
|
|
def recurse(self, do):
|
|
if self.root == None:
|
|
return
|
|
self.root.recurse(do)
|
|
def find(self, node):
|
|
return self.root.find(node)
|
|
def remove(self, node):
|
|
self.root.remove(node)
|
|
def copy(self):
|
|
"make true copy of self"
|
|
t = newTree()
|
|
c = NodeOp()
|
|
self.recurse(c.copy)
|
|
t.fromList(c.list)
|
|
return t
|
|
def asList(self):
|
|
c = NodeOp()
|
|
self.recurse(c.copy)
|
|
return c.list
|
|
def fromList(self, list):
|
|
for item in list:
|
|
n = Node(item)
|
|
self.insert(n)
|
|
def insertcopy(self, node):
|
|
n = node.copy()
|
|
self.insert(n)
|
|
def merge(self, other):
|
|
other.recurse(self.insertcopy)
|
|
# EXAMPLE:
|
|
|
|
newTree = Tree
|
|
|
|
def printnode(x):
|
|
print "Element: %s, depth: %s" % (x, x.depth)
|
|
|
|
def test():
|
|
a = [5, 8, 8, 3, 7, 9]
|
|
t1 = Tree()
|
|
t1.fromList(a)
|
|
|
|
b = [12, 4, 56, 7, 34]
|
|
t2 = Tree()
|
|
t2.fromList(b)
|
|
|
|
print "tree1:"
|
|
print t1.asList()
|
|
print "tree2:"
|
|
print t2.asList()
|
|
print '-----'
|
|
print "Trees can be added:"
|
|
|
|
|
|
t3 = t1 + t2
|
|
print t3.asList()
|
|
print "..or alternatively merged:"
|
|
t1.merge(t2)
|
|
print t1.asList()
|
|
|
|
if __name__ == '__main__':
|
|
test()
|