【问题标题】:Golang pointer receiver not updating as expectedGolang 指针接收器未按预期更新
【发布时间】:2022-09-22 22:37:02
【问题描述】:

我正在二叉搜索树中实现节点删除。我已经实现了一个看起来不错的方法(从算法的角度来看)。但不工作。在花了几个小时试图理解为什么之后,我很想从你那里得到一些帮助。

BST 定义

    type Node struct {
    Data  int
    Left  *Node
    Right *Node
}

辅助方法(它们已经过测试并且有效)

// Find checks whether some data exist in the bst and returns the corresponding node
func (bst *Node) Find(data int) *Node {
    if bst == nil {
        return bst
    }
    if bst.Data == data {
        return bst
    }
    if data < bst.Data {
        return bst.Left.Find(data)
    }
    return bst.Right.Find(data)
}

// Min returns the smallest element in a bst
func (bst *Node) Min() *Node {
    if bst == nil {
        return nil
    }
    current := bst
    for current.Left != nil {
        current = current.Left
    }
    return current
}

非工作方法

// Delete removes a key from the binary tree
func (bst *Node) Delete(data int) *Node {
    if bst == nil {
        return bst
    }
    current := bst
    toDelete := current.Find(data)
    if toDelete == nil {
        return current
    }
    if toDelete.Right == nil && toDelete.Left != nil {
        toDelete = toDelete.Left
        return current
    }
    if toDelete.Right != nil && toDelete.Left == nil {
        toDelete = toDelete.Right
        return current
    }
    inOrderSuccessor := toDelete.Right.Min()
    toDelete = inOrderSuccessor
    return current
}

测试

func main() {
    root := bst.New(8)
    root.Left = bst.New(3)
    root.Right = bst.New(10)
    root.Left.Left = bst.New(1)
    root.Left.Right = bst.New(6)
    fmt.Println(root.InOrder())
    root = root.Delete(3)
    fmt.Println(root.InOrder())
}

output
1->3->6->8->10->
1->3->6->8->10->

Delete 方法有问题,但我不明白为什么。

  • bst.New() 方法是这样定义的。 // New returns a pointer to a mew node (like the new construct in Go) func New(data int) *Node { return &amp;Node{Data: data}
  • 请更新问题,而不是将代码放入 cmets。一个完全的minimal reproducible example 也会有很大帮助

标签: algorithm go binary-tree


【解决方案1】:

我假设你认为

toDelete = toDelete.Left

覆盖存储在toDelete 指向的位置的数据。 但是这个操作只会给toDeletevariable 分配一个新的指针。要覆盖存储在内存中的数据,您需要取消引用指针:

*toDelete = *toDelete.Left

您可以查看此示例 https://go.dev/play/p/M62hd3lpHXk 并在更简单的情况下查看差异。

【讨论】:

    猜你喜欢
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-12
    • 2016-02-29
    • 2021-11-22
    • 2018-08-08
    相关资源
    最近更新 更多