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

AVL 树是一种自平衡二叉搜索树,它可以在 O(log n) 时间内完成查找、插入和删除操作。以下是 Python 实现 AVL 树的示例代码: ```python # AVL 树节点类 class AVLNode: def __init__(self, key): self.key = key self.left = None self.right = None self.height = 1 # AVL 树类 class AVLTree: def __init__(self): self.root = None # 获取节点高度 def get_height(self, node): if node is None: return 0 return node.height # 获取节点的平衡因子 def get_balance_factor(self, node): if node is None: return 0 return self.get_height(node.left) - self.get_height(node.right) # 右旋转 def rotate_right(self, node): left_child = node.left left_right_child = left_child.right left_child.right = node node.left = left_right_child node.height = 1 + max(self.get_height(node.left), self.get_height(node.right)) left_child.height = 1 + max(self.get_height(left_child.left), self.get_height(left_child.right)) return left_child # 左旋转 def rotate_left(self, node): right_child = node.right right_left_child = right_child.left right_child.left = node node.right = right_left_child node.height = 1 + max(self.get_height(node.left), self.get_height(node.right)) right_child.height = 1 + max(self.get_height(right_child.left), self.get_height(right_child.right)) return right_child # 插入节点 def insert(self, key): def insert_node(node, key): if node is None: return AVLNode(key) elif key < node.key: node.left = insert_node(node.left, key) else: node.right = insert_node(node.right, key) node.height = 1 + max(self.get_height(node.left), self.get_height(node.right)) balance_factor = self.get_balance_factor(node) # 左旋转 if balance_factor > 1 and key < node.left.key: return self.rotate_right(node) # 右旋转 if balance_factor < -1 and key > node.right.key: return self.rotate_left(node) # 左右旋转 if balance_factor > 1 and key > node.left.key: node.left = self.rotate_left(node.left) return self.rotate_right(node) # 右左旋转 if balance_factor < -1 and key < node.right.key: node.right = self.rotate_right(node.right) return self.rotate_left(node) return node self.root = insert_node(self.root, key) # 删除节点 def delete(self, key): def delete_node(node, key): if node is None: return node elif key < node.key: node.left = delete_node(node.left, key) elif key > node.key: node.right = delete_node(node.right, key) else: # 节点只有一个子节点或没有子节点 if node.left is None: temp = node.right node = None return temp elif node.right is None: temp = node.left node = None return temp # 节点有两个子节点 temp = self.get_min_node(node.right) node.key = temp.key node.right = delete_node(node.right, temp.key) if node is None: return node node.height = 1 + max(self.get_height(node.left), self.get_height(node.right)) balance_factor = self.get_balance_factor(node) # 左旋转 if balance_factor > 1 and self.get_balance_factor(node.left) >= 0: return self.rotate_right(node) # 右旋转 if balance_factor < -1 and self.get_balance_factor(node.right) <= 0: return self.rotate_left(node) # 左右旋转 if balance_factor > 1 and self.get_balance_factor(node.left) < 0: node.left = self.rotate_left(node.left) return self.rotate_right(node) # 右左旋转 if balance_factor < -1 and self.get_balance_factor(node.right) > 0: node.right = self.rotate_right(node.right) return self.rotate_left(node) return node self.root = delete_node(self.root, key) # 获取最小节点 def get_min_node(self, node): if node is None or node.left is None: return node return self.get_min_node(node.left) # 中序遍历 def inorder_traversal(self): def inorder(node): if node is not None: inorder(node.left) print(node.key, end=" ") inorder(node.right) inorder(self.root) ``` 示例用法: ```python avl_tree = AVLTree() avl_tree.insert(10) avl_tree.insert(20) avl_tree.insert(30) avl_tree.insert(40) avl_tree.insert(50) avl_tree.insert(25) avl_tree.inorder_traversal() avl_tree.delete(30) avl_tree.inorder_traversal() ``` 输出结果: ``` 10 20 25 30 40 50 10 20 25 40 50 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值