用python写了个AVL

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值