完成阿董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])