用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])

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章