📌  相关文章
📜  二叉树,二叉搜索树和AVL树中不同操作的复杂性(1)

📅  最后修改于: 2023-12-03 15:06:20.128000             🧑  作者: Mango

二叉树,二叉搜索树和AVL树中不同操作的复杂性

在计算机科学中,二叉树、二叉搜索树和AVL树都是常见的树结构。虽然它们有许多相似之处,但在不同的操作上,它们的复杂性是不同的。下面我们将分别对它们进行介绍。

二叉树

二叉树是一种每个节点最多只有两个子节点的树结构。二叉树的操作包括插入、删除和查找。

二叉树中插入、删除和查找的复杂性都是O(n),其中n是树的节点数。这是因为插入、删除或查找可能需要遍历整个树。

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class BinaryTree:
    def __init__(self):
        self.root = None
    
    def insert(self, val):
        if not self.root:
            self.root = TreeNode(val)
            return
        
        queue = [self.root]
        while queue:
            cur = queue.pop(0)
            if not cur.left:
                cur.left = TreeNode(val)
                return
            elif not cur.right:
                cur.right = TreeNode(val)
                return
            else:
                queue.append(cur.left)
                queue.append(cur.right)
    
    def delete(self, val):
        if not self.root:
            return
        
        parent, node, is_left_child = self._find_node(val)
        if not node:
            return
        
        if not node.left and not node.right:
            if not parent:
                self.root = None
            elif is_left_child:
                parent.left = None
            else:
                parent.right = None
        elif node.left and node.right:
            next_node = node.right
            while next_node.left:
                next_node = next_node.left
            next_val = next_node.val
            self.delete(next_val)
            node.val = next_val
        else:
            next_node = node.left or node.right
            if not parent:
                self.root = next_node
            elif is_left_child:
                parent.left = next_node
            else:
                parent.right = next_node
    
    def search(self, val):
        queue = [self.root]
        while queue:
            cur = queue.pop(0)
            if cur.val == val:
                return True
            if cur.left:
                queue.append(cur.left)
            if cur.right:
                queue.append(cur.right)
        return False
    
    def _find_node(self, val):
        if not self.root:
            return None, None, None
        
        parent, node, is_left_child = None, self.root, None
        queue = [(parent, node, is_left_child)]
        while queue:
            parent, node, is_left_child = queue.pop(0)
            if node.val == val:
                return parent, node, is_left_child
            if node.left:
                queue.append((node, node.left, True))
            if node.right:
                queue.append((node, node.right, False))
        return None, None, None
二叉搜索树

二叉搜索树(BST)是一种二叉树,其每个节点的左子树中所有节点的值都小于该节点的值,右子树中所有节点的值都大于该节点的值。BST的操作包括插入、删除和查找。

在理想情况下,BST中插入、删除和查找的复杂性都是O(log n),其中n是树的节点数。但是,如果BST退化为链表,则复杂性将退化为O(n)。

class BinarySearchTree:
    def __init__(self):
        self.root = None
    
    def insert(self, val):
        if not self.root:
            self.root = TreeNode(val)
            return
        
        cur = self.root
        while True:
            if val < cur.val:
                if not cur.left:
                    cur.left = TreeNode(val)
                    return
                else:
                    cur = cur.left
            elif val > cur.val:
                if not cur.right:
                    cur.right = TreeNode(val)
                    return
                else:
                    cur = cur.right
            else:
                return
    
    def delete(self, val):
        if not self.root:
            return
        
        parent, node = self._find_node(val)
        if not node:
            return
        
        if not node.left and not node.right:
            if not parent:
                self.root = None
            elif parent.left == node:
                parent.left = None
            else:
                parent.right = None
        elif node.left and node.right:
            next_node = node.right
            while next_node.left:
                next_node = next_node.left
            next_val = next_node.val
            self.delete(next_val)
            node.val = next_val
        else:
            next_node = node.left or node.right
            if not parent:
                self.root = next_node
            elif parent.left == node:
                parent.left = next_node
            else:
                parent.right = next_node
    
    def search(self, val):
        cur = self.root
        while cur:
            if cur.val == val:
                return True
            elif val < cur.val:
                cur = cur.left
            else:
                cur = cur.right
        return False
    
    def _find_node(self, val):
        if not self.root:
            return None, None
        
        parent, node = None, self.root
        while node:
            if node.val == val:
                return parent, node
            elif val < node.val:
                parent = node
                node = node.left
            else:
                parent = node
                node = node.right
        return None, None
AVL树

AVL树是一种自平衡的BST,它确保了总是保持平衡。AVL树的操作包括插入、删除和查找。

AVL树中插入、删除和查找的复杂性都是O(log n),其中n是树的节点数。这是因为AVL树保持平衡,所以树的高度始终是log n。

class AVLNode:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        self.height = 1

class AVLTree:
    def __init__(self):
        self.root = None
    
    def insert(self, val):
        self.root = self._insert(self.root, val)
    
    def _insert(self, node, val):
        if not node:
            return AVLNode(val)
        
        if val < node.val:
            node.left = self._insert(node.left, val)
        else:
            node.right = self._insert(node.right, val)
        
        node.height = 1 + max(self._get_height(node.left), self._get_height(node.right))
        balance = self._get_balance(node)
        
        if balance > 1 and val < node.left.val:
            return self._right_rotate(node)
        
        if balance < -1 and val > node.right.val:
            return self._left_rotate(node)
        
        if balance > 1 and val > node.left.val:
            node.left = self._left_rotate(node.left)
            return self._right_rotate(node)
        
        if balance < -1 and val < node.right.val:
            node.right = self._right_rotate(node.right)
            return self._left_rotate(node)
        
        return node
    
    def delete(self, val):
        self.root = self._delete(self.root, val)
    
    def _delete(self, node, val):
        if not node:
            return node
        
        if val < node.val:
            node.left = self._delete(node.left, val)
        elif val > node.val:
            node.right = self._delete(node.right, val)
        else:
            if not node.left and not node.right:
                node = None
            elif not node.left:
                node = node.right
            elif not node.right:
                node = node.left
            else:
                right_min_node = self._get_min_node(node.right)
                node.val = right_min_node.val
                node.right = self._delete(node.right, right_min_node.val)
        
        if not node:
            return node
        
        node.height = 1 + max(self._get_height(node.left), self._get_height(node.right))
        balance = self._get_balance(node)
        
        if balance > 1 and self._get_balance(node.left) >= 0:
            return self._right_rotate(node)
        
        if balance < -1 and self._get_balance(node.right) <= 0:
            return self._left_rotate(node)
        
        if balance > 1 and self._get_balance(node.left) < 0:
            node.left = self._left_rotate(node.left)
            return self._right_rotate(node)
        
        if balance < -1 and self._get_balance(node.right) > 0:
            node.right = self._right_rotate(node.right)
            return self._left_rotate(node)
        
        return node
    
    def search(self, val):
        cur = self.root
        while cur:
            if cur.val == val:
                return True
            elif val < cur.val:
                cur = cur.left
            else:
                cur = cur.right
        return False
    
    def _get_height(self, node):
        if not node:
            return 0
        return node.height
    
    def _get_balance(self, node):
        if not node:
            return 0
        return self._get_height(node.left) - self._get_height(node.right)
    
    def _left_rotate(self, node):
        new_node = node.right
        node.right = new_node.left
        new_node.left = node
        
        node.height = 1 + max(self._get_height(node.left), self._get_height(node.right))
        new_node.height = 1 + max(self._get_height(new_node.left), self._get_height(new_node.right))
        
        return new_node
    
    def _right_rotate(self, node):
        new_node = node.left
        node.left = new_node.right
        new_node.right = node
        
        node.height = 1 + max(self._get_height(node.left), self._get_height(node.right))
        new_node.height = 1 + max(self._get_height(new_node.left), self._get_height(new_node.right))
        
        return new_node
    
    def _get_min_node(self, node):
        while node.left:
            node = node.left
        return node

以上是二叉树、二叉搜索树和AVL树中不同操作的复杂性的介绍。在进行操作时,我们可以根据需求选择不同的树结构以达到最高效的操作。