ZBLOG

golang 二叉查找树

二叉查找树(Binary Search Tree,简称 BST)是一种常用的数据结构,它具有以下特点:

  1. 左子树上所有节点的值均小于其父节点的值。

  2. 右子树上所有节点的值均大于其父节点的值。

  3. 左右子树也分别为二叉查找树。

在 golang 中实现一个二叉查找树可以使用如下代码:

type Node struct {
    value int   // 节点存储的值
    left  *Node // 左子节点指针
    right *Node // 右子节点指针
}

// 插入新元素
func (n *Node) Insert(value int) *Node {
    if n == nil { // 当前节点为空,创建一个新节点并返回
        return &Node{value: value}
    }
    if value < n.value { // 插入左子树
        n.left = n.left.Insert(value)
    } else if value > n.value { // 插入右子树
        n.right = n.right.Insert(value)
    }
    return n 
}

// 查找元素是否存在
func (n *Node) Search(value int) bool {
    if n == nil { // 根节点为空,直接返回 false 
        return false 
    }
    if value == n.value { // 找到了目标元素 
        return true 
    } else if value < n.value { // 在左子树中查找 
        return n.left.Search(value)
    } else { // 在右子树中查找 
        return n.right.Search(value)
    }
}

// 删除指定元素
func (n *Node) Delete(value int) *Node {
    if n == nil { // 根节点为空,直接返回 
        return nil 
    }
    if value < n.value { // 在左子树中删除目标元素 
        n.left = n.left.Delete(value)
        return n
    } else if value > n.value { // 在右子树中删除目标元素 
        n.right = n.right.Delete(value)
        return n 
    } else { // 找到了目标元素
        if n.left == nil && n.right == nil { // 情况1:没有子节点,直接删除 
            return nil
        } else if n.left == nil || n.right == nil { // 情况2:只有一个子节点,用该子节点替换当前节点即可 
            var child *Node
            if n.left != nil {
                child = n.left
            } else {
                child = n.right
            }
            return child 
        } else { // 情况3:有两个子节点,找到右子树的最小值来替换当前节点,并在右子树中递归删除该最小值节点。  
            min := findMin(n.right)
            minCopy := &Node{value: min}
            right := deleteMin(n.right)
            minCopy.left, minCopy.right = n.left, right
            return minCopy
        }
    }
}

// 查找右子树的最小值(用于删除情况3)
func findMin(n *Node) int {
    for ;n.left != nil; {
        n = n.left
    }
    return n.value 
}

// 删除右子树的最小值(用于删除情况3)
func deleteMin(n *Node) *Node {
    if n.left == nil {
        return n.right 
    }
    n.left = deleteMin(n.left)
    return n 
}

在该代码中,我们使用 Node 结构体来表示二叉查找树的节点,其中包含一个 value 值和左右子节点指针。具体实现如下:

  1. 插入新元素:从根节点开始遍历 BST,如果当前节点为空,则创建一个新节点并返回;否则比较插入值与当前节点值的大小关系,选择向左子树或右子树递归插入。

  2. 查找元素是否存在:从根节点开始遍历 BST,如果当前节点为空,则说明未找到目标元素;否则比较查找值与当前节点值的大小关系,选择向左子树或右子树递归查找。

  3. 删除指定元素:从根节点开始遍历 BST,如果当前节点为空,则说明未找到目标元素;否则比较删除值与当前节点值的大小关系,选择向左子树或右子树递归删除。对于要删除的三种情况分别进行处理:没有子节点直接删除、只有一个子节点用该子节点替换、有两个子节点则将其替换为右子树中最小值,并在右子树中递归删除该最小值节点。

时间复杂度:插入、查找和删除操作的平均时间复杂度为 \(O(log n)\),但在最坏情况下可能会退化成链表,时间复杂度为 \(O(n)\)

空间复杂度:\(O(n)\)

稳定性:不稳定

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=6494

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?