完成阿董n天前布置的作业。由于各种原因此事一拖再拖,今晚终于一鼓作气写了个1.0版……几个测试用例基本可以覆盖左平衡与右平衡的多数逻辑,但应该不是完全覆盖。
# -*- coding: utf-8 -*-
#! Balanced Binary Tree
#! create balanced binary tree
class BSTNode:
# 'balanced binary tree node'
data = None # element data
bf = None #balance factor
lchild = None # left child
rchild = None # right child
def set_obj(self, obj):
self.data = obj.data
self.bf = obj.bf
self.lchild = obj.lchild
self.rchild = obj.rchild
class Taller:
t = False
class BSTvessel:
#! root node of the BST
root = None
taller = None
#! balance factor
bf_min_leaf = None
bf_max_leaf = None
#! this list storage all the element of BSD node in the vessel
vessel = None
#! we can construct BST, and execute search operate
def __init__(self, list):
print 'Now you construct the BST vessel.'
self.vessel = list
print self.vessel
print "Now create root..."
self.root = BSTNode()
self.taller = Taller()
def initial(self, type):
if type == 1:
# only insert binary
for i in self.vessel:
self.insert(i)
else:
print "Create BST..."
for i in self.vessel:
i = int(i)
self.ins_node(self.root, i, self.taller)
def output_sequence(self):
print "Now we should output the sequence of binary tree."
self.walk_binary_tree(self.root)
def walk_binary_tree(self, node):
if node.data == None:
return
self.walk_binary_tree(node.lchild)
print "%d " % node.data
self.walk_binary_tree(node.rchild)
def ins_node(self, node, element, taller):
"insert a node, and keep it is a BST."
print "insert element: %d" % element
#pdb.set_trace()
if node.data == None:
print "node is None."
node.data = element
node.bf = 0
node.lchild = BSTNode()
node.rchild = BSTNode()
taller.t = True
return True
else:
if node.data == element:
# 如果树中已经有与该元素相等的节点,则不应该再进行插入了
taller.t = False
return False
if node.data > element:
# 在T的左子树当中进行搜索
if self.ins_node(node.lchild, element, taller) == False:
# 没有插入,返回false
return False
if taller.t == True:
# 检查平衡度
if node.bf == 1:
# 左高
self.left_balance(node)
taller.t = False
elif node.bf == 0:
# 等高
node.bf = 1
taller.t = True
elif node.bf == -1:
# 右高
node.bf = 0
taller.t = False
else:
print "unexpection!!!"
else:
# 继续在右子树进行搜索
if self.ins_node(node.rchild, element, taller) == False:
# 未插入
return False
if taller.t == True:
# 检查平衡度
if node.bf == 1:
# 左高
node.bf = 0
taller.t = False
elif node.bf == 0:
# 等高
node.bf = -1
taller.t = True
elif node.bf == -1:
# 右高
self.right_balance(node)
taller.t = False
else:
print "unexpection!!!"
return True
def left_balance(self, node):
# 对以node为根节点的二叉树作左平衡旋转,本算法结束,node将变成新的根节点
print "left balance."
lc = node.lchild
if lc.bf == 1:
# 检查node的左子树的平衡度,并做相应的平衡处理
node.bf = lc.bf = 0
self.r_rotate(node)
elif lc.bf == -1:
rd = lc.rchild
# 根据具体情况的不同,分为三种情况进行处理
# 主要取决于根结点左孩子的右孩子的孩子的情况
if rd.bf == 1:
node.bf = -1
lc.bf = 0
elif rd.bf == 0:
node.bf = lc.bf = 0
elif rd.bf == -1:
node.bf = 0
lc.bf = 1
else:
print "unexpection!!!"
rd.bf = 0
self.l_rotate(node.lchild)
self.r_rotate(node)
return node
def right_balance(self, node):
# 对于以node为根结点的二叉树作右平衡旋转,本算法结束,node将变成新的根节点
print "right balance."
rc = node.rchild
if rc.bf == -1:
node.bf = rc.bf = 0
self.l_rotate(node)
elif rc.bf == 1:
ld = rc.lchild
# 主要取决于根结点的右孩子的左孩子的孩子的情况
if ld.bf == 1:
node.bf = 0
rc.bf = -1
elif ld.bf == 0:
node.bf = rc.bf = 0
elif ld.bf == -1:
node.bf = 1
rc.bf = 0
else:
print "unexpection!!!"
ld.bf = 0
self.r_rotate(node.rchild)
self.l_rotate(node)
def r_rotate(self, node):
# 对于以node为根的二叉排序树作右旋处理,处理之后,node指向新树的根节点
print "r_rotate"
lc = BSTNode()
lc.set_obj(node.lchild) # lc指向node的左子树作为根结点
node.lchild.set_obj(lc.rchild)
lc.rchild.set_obj(node)
node.set_obj(lc)
def l_rotate(self, node):
# 左旋转
print "l_rotate"
rc = BSTNode()
rc.set_obj(node.rchild)
node.rchild.set_obj(rc.lchild)
rc.lchild.set_obj(node)
node.set_obj(rc)
class Test:
def __init__(self):
print "construct test model."
def test_create(self, list):
tree = BSTvessel(list)
tree.initial(2)
tree.output_sequence()
if __name__ == '__main__':
t = Test()
source = [[3,2,1],[1,2,3],[1,2,3,3,2,1],[10,15,6,8,4,3],[11,6,15,4,9,16,3,5,8,10,7],[10,6,15,13,17,20],[10,6,20,4,8,15,30,13,17,27,35,11], [10,6,20,4,8,15,30,13,17,27,35,12], [10,6,15,13,17,16], [12,6,15,4,11,16,3,5,8,10,7],[12,6,15,4,11,16,3,5,8,10,9],[10,15,6,8,4,5],[10,6,20,4,8,15,30,13,17,27,35,11,11,6,15,4,9,16,3,5,8,10,7]]
print source
for i in range(len(source)):
t.test_create(source[i])