📅  最后修改于: 2023-12-03 15:06:20.128000             🧑  作者: Mango
在计算机科学中,二叉树、二叉搜索树和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树是一种自平衡的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树中不同操作的复杂性的介绍。在进行操作时,我们可以根据需求选择不同的树结构以达到最高效的操作。