📜  二进制搜索树(BST)(1)

📅  最后修改于: 2023-12-03 14:49:02.188000             🧑  作者: Mango

二进制搜索树 (BST)

二进制搜索树 (Binary Search Tree, BST) 是一种基于二叉树实现的数据结构。它的特点是每个节点都包含一个关键字,且每个节点的关键字值不同。对于每个节点都有一个左子树和右子树,使得左子树中所有的节点的关键字小于它的根节点的关键字,而右子树中所有节点的关键字大于它的根节点的关键字。

在 BST 中,我们可以快速地查找、插入和删除节点。其中:查找和插入节点的时间复杂度为 O(log n),而删除节点的时间复杂度主要由删除位置和树的形态决定,最坏情况下为 O(n)。

实现思路

下面我们来一步步介绍如何实现二进制搜索树。

首先,我们需要一个节点类,它包含关键字、左右子树等多个属性,如下:

class Node:
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None

接着,我们需要一个 BST 类,它包含插入、查找、删除等多个方法。

插入节点

插入节点的思路大致如下:

  1. 如果树为空,将新节点作为根节点。
  2. 如果新节点的值小于当前节点的值,将新节点插入到当前节点的左子树中。
  3. 如果新节点的值大于当前节点的值,将新节点插入到当前节点的右子树中。

代码实现如下:

class BST:
    def __init__(self):
        self.root = None
        
    def insert(self, key):
        if not self.root:
            self.root = Node(key)
        else:
            self._insert(key, self.root)
            
    def _insert(self, key, node):
        if key < node.key:
            if not node.left:
                node.left = Node(key)
            else:
                self._insert(key, node.left)
        else:
            if not node.right:
                node.right = Node(key)
            else:
                self._insert(key, node.right)
查找节点

查找节点的思路大致如下:

  1. 如果树为空,返回 None。
  2. 如果当前节点的值等于目标值,返回当前节点。
  3. 如果目标值小于当前节点的值,递归地查找左子树。
  4. 如果目标值大于当前节点的值,递归地查找右子树。

代码实现如下:

class BST:
    def __init__(self):
        self.root = None
        
    def insert(self, key):
        if not self.root:
            self.root = Node(key)
        else:
            self._insert(key, self.root)
            
    def _insert(self, key, node):
        if key < node.key:
            if not node.left:
                node.left = Node(key)
            else:
                self._insert(key, node.left)
        else:
            if not node.right:
                node.right = Node(key)
            else:
                self._insert(key, node.right)
                
    def find(self, key):
        return self._find(key, self.root)
    
    def _find(self, key, node):
        if not node:
            return None
        if node.key == key:
            return node
        elif key < node.key:
            return self._find(key, node.left)
        else:
            return self._find(key, node.right)
删除节点

删除节点是比较复杂的操作,我们需要考虑以下三种情况:

  1. 节点没有子节点
  2. 节点只有一个子节点
  3. 节点有两个子节点

删除操作的具体实现如下:

class BST:
    def __init__(self):
        self.root = None
        
    def insert(self, key):
        if not self.root:
            self.root = Node(key)
        else:
            self._insert(key, self.root)
            
    def _insert(self, key, node):
        if key < node.key:
            if not node.left:
                node.left = Node(key)
            else:
                self._insert(key, node.left)
        else:
            if not node.right:
                node.right = Node(key)
            else:
                self._insert(key, node.right)
                
    def find(self, key):
        return self._find(key, self.root)
    
    def _find(self, key, node):
        if not node:
            return None
        if node.key == key:
            return node
        elif key < node.key:
            return self._find(key, node.left)
        else:
            return self._find(key, node.right)
        
    def delete(self, key):
        self._delete(None, self.root, key)
        
    def _delete(self, parent, node, key):
        if not node:
            return
        
        if key == node.key:
            # 如果节点没有子节点
            if not node.left and not node.right:
                if node == self.root:
                    self.root = None
                elif parent.left == node:
                    parent.left = None
                else:
                    parent.right = None
            # 如果节点只有一个子节点
            elif not node.left and node.right:
                if node == self.root:
                    self.root = node.right
                elif parent.left == node:
                    parent.left = node.right
                else:
                    parent.right = node.right
            elif node.left and not node.right:
                if node == self.root:
                    self.root = node.left
                elif parent.left == node:
                    parent.left = node.left
                else:
                    parent.right = node.left
            # 如果节点有两个子节点
            else:
                min_node_parent = node
                min_node = node.right
                while min_node.left:
                    min_node_parent = min_node
                    min_node = min_node.left
                node.key = min_node.key
                self._delete(min_node_parent, min_node, min_node.key)
        elif key < node.key:
            self._delete(node, node.left, key)
        else:
            self._delete(node, node.right, key)
总结

二进制搜索树是一种常用的数据结构,它具有快速查找、插入和删除节点的特点。在实现时,我们要注意处理节点没有子节点、节点只有一个子节点以及节点有两个子节点的情况。