Binary Seach Tree(BST) , BST Sort, and AVL Tree

Binary Seach Tree(BST): left<root<right

  • height of tree is expected to be smaller
  • insert while keep tree balanced: read black tree (faster insertion) or AVL tree(lower hight
class Node:
    def __init__(self, data):
        self.left = None
        self.right = None
        self.parent = None
        self.data = data
        self.height = 0

class BinaryTree:

    def __init__(self):
        self.root = None

    def __str__(self, node = 0, depth = 0, direction_label = ""):
        "The tree structure in string form, to be used in str(my_node) or print(my_node)."
        if node == 0:
            node = self.root
        if node:
            height_info = "(H"+str(node.height)+")" if node.height > 0 else ""
            return depth * "\t" + direction_label + height_info + str(node.data) + "\n" + \
                self.__str__(node.left, depth+1, "L:") + self.__str__(node.right, depth+1, "R:")
        else:
            return ""

    def inorder(self, node = 0, result = None):
        if result is None:
            result = []
        if node == 0:
            node = self.root
        if node:
            self.inorder(node.left, result)
            result.append(node.data)
            self.inorder(node.right, result)
        return result


class Node(binary_tree.Node):
    def left_height(self):
        return -1 if self.left is None else self.left.height
    def right_height(self):
        return -1 if self.right is None else self.right.height
    def update_height(self):
        self.height = max(self.left_height(), self.right_height()) + 1
    def balance(self):
        "-2, -1: left heavy, 1, 2: right heavy"
        return self.right_height() - self.left_height()

class BinarySearchTree(binary_tree.BinaryTree):
    def __init__(self, data_array = []):
        self.root = None
        for data in data_array:
            self.insert(Node(data))
            # print()
            # print(self)
            # print()
    
    def insert(self, new_node, node = 0):
        if not self.root:
            self.root = new_node
            return new_node
        if node == 0:
            node = self.root
        if new_node.data < node.data:
            if node.left:
                self.insert(new_node, node.left)
            else:
                new_node.parent = node
                node.left = new_node
        else:
            if node.right:
                self.insert(new_node, node.right)
            else:
                new_node.parent = node
                node.right = new_node
        node.update_height()

    def sort(self):
        return self.inorder()

def BST_sort(array):
    my_tree = BinarySearchTree(array)
    return my_tree.sort()

if __name__ == "__main__":
    tree = BinarySearchTree([0,3,7,5,2,1,9,10])
    tree.insert(Node(-1))
    print(tree)
    print(tree.sort())
    tree = BinarySearchTree(["Zhao", "Qian", "Sun","Li", "Zhou", "Wu", "Zheng", "Wang"])
    print(tree)
    print(tree.sort())

AVL Tree

class Node(binary_search_tree.Node):
    pass

class AVLTree(binary_search_tree.BinarySearchTree):
    def insert(self, new_node, node = 0):
        super().insert(new_node, node)
        self.check_fix_AVL(new_node.parent)
        return new_node
    
    def update_all_heights_upwards(self, node):
        node.update_height()
        if node is not self.root:
            self.update_all_heights_upwards(node.parent)
    
    def _left_rotate(self, x): 
        # x, y, B notation follows MIT 6.006 Lecture 6.
        y = x.right
        B = y.left
        y.parent = x.parent
        y.left = x
        x.parent = y
        x.right = B
        if B is not None:
            B.parent = x
        if y.parent is None:
            self.root = y
        elif y.parent.left == x:
            y.parent.left = y
        else:
            y.parent.right = y
        self.update_all_heights_upwards(x)

    def _right_rotate(self,x):
        y = x.left
        B = y.right
        y.parent = x.parent
        y.right = x
        x.parent = y
        x.left = B
        if B is not None:
            B.parent = x
        if y.parent is None:
            self.root = y
        elif y.parent.right == x:
            y.parent.right = y
        else:
            y.parent.left = y
        self.update_all_heights_upwards(x)

    def check_fix_AVL(self, node):
        if node is None:
            return
        if abs(node.balance()) < 2:
            self.check_fix_AVL(node.parent)
            return
        if node.balance() == 2: # right too heavy
            if node.right.balance() >= 0:
                self._left_rotate(node)
            else:
                self._right_rotate(node.right)
                self._left_rotate(node)
        else: # node.balance() == -2, left too heavy
            if node.left.balance() <= 0:
                self._right_rotate(node)
            else:
                self._left_rotate(node.left)
                self._right_rotate(node)
        self.check_fix_AVL(node.parent)

def AVL_sort(array):
    my_tree = AVLTree(array)
    return my_tree.sort()

if __name__ == "__main__":

    # tree = AVLTree([0,3,7,5,2,1,9,10,11,12,13,14,15,16,17,-1,-2,-3,-4,-5,-5])
    # print(tree)
    # print(tree.sort())
    # tree = AVLTree(["Zhao", "Qian", "Sun","Li", "Zhou", "Wu", "Zheng", "Wang"])
    # print(tree)
    # print(tree.sort())
    # print(AVL_sort(["Zhao", "Qian", "Sun","Li", "Zhou", "Wu", "Zheng", "Wang"]))

    tree = AVLTree([5.2, 5.6, 8.6, 9.3, 4.2, 57.6, 7.6, 15.9, 29.3, 13.1, 5.0, 6.0])
    print(tree)
    print(tree.sort())

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值