Rust 二叉树插入实现困难

Rust 二叉树插入实现困难,rust,binary-tree,ownership,Rust,Binary Tree,Ownership,我看过很多主题,但我找不到任何线索来解释为什么我的代码无法编译(当然除了所有权问题),希望这里有人能帮助我 我正在研究一个二叉树实现,它的一个函数是insert函数。这是我第一次用Rust编写代码,尽管我已经看过很多次文档,但我无法找出以下代码中的所有权有什么问题(我希望我只发布了所有相关代码): 它与框或左/右分配有关吗?您正试图将已装箱的节点移出其封闭选项。这是不允许的,因为之后这些选项仍将由相应的父节点拥有。理论上,您可以调用take选项来移动节点take将值移出选项,并将其替换为None

我看过很多主题,但我找不到任何线索来解释为什么我的代码无法编译(当然除了所有权问题),希望这里有人能帮助我

我正在研究一个二叉树实现,它的一个函数是insert函数。这是我第一次用Rust编写代码,尽管我已经看过很多次文档,但我无法找出以下代码中的所有权有什么问题(我希望我只发布了所有相关代码):


它与
或左/右分配有关吗?

您正试图将已装箱的节点移出其封闭选项。这是不允许的,因为之后这些选项仍将由相应的父节点拥有。理论上,您可以调用
take
选项来移动节点
take
将值移出选项,并将其替换为
None
,而不是将其保留为“空”(不允许)

但是,这将有效地将子节点与其各自的父节点分离。插入新节点返回后,必须重新连接它们:

fn node_insert(n: Node, mut n2: Box<Node>) -> Box<Node>{
    let i = SortedContainer::data_compare(&n.value, &n2.value);
    if i < 0 {
        n2.right = match n2.right.take() {
            Some(rightnode) => Some(SortedContainer::node_insert(n, rightnode)),
            None => Some(Box::new(n)),
        }
    } else if i > 0 {
        n2.left = match n2.left.take() {
            Some(leftnode) => Some(SortedContainer::node_insert(n, leftnode)),
            None => Some(Box::new(n)),
        }
    }
    n2
}
另一种解决方案是将可变引用传递给节点,而不是移动它们。这是可行的,因为您实际上只需要沿着从根节点到叶节点(新节点应该插入到该节点)的路径对节点进行变异:

fn node_insert(n: Node, n2: &mut Node) {
    let i = SortedContainer::data_compare(&n.value, &n2.value);
    if i < 0 {
        match n2.right {
            Some(ref mut rightnode) => SortedContainer::node_insert(n, rightnode),
            None => n2.right = Some(Box::new(n)),
        }
    } else if i > 0 {
        match n2.left {
            Some(ref mut leftnode) => SortedContainer::node_insert(n, leftnode),
            None => n2.left = Some(Box::new(n)),
        }
    }
}

这可能是相关的,第一次使用Rust编码——您应该从其他地方开始。我强烈建议您为
数据实现
,而不是您自己的定制函数。我还没有发现这种特性,谢谢!
self.root = match self.root.take() {
    Some(rootnode) => Some(SortedContainer::node_insert(n, rootnode)),
    None => Some(Box::new(n)),
}
fn node_insert(n: Node, n2: &mut Node) {
    let i = SortedContainer::data_compare(&n.value, &n2.value);
    if i < 0 {
        match n2.right {
            Some(ref mut rightnode) => SortedContainer::node_insert(n, rightnode),
            None => n2.right = Some(Box::new(n)),
        }
    } else if i > 0 {
        match n2.left {
            Some(ref mut leftnode) => SortedContainer::node_insert(n, leftnode),
            None => n2.left = Some(Box::new(n)),
        }
    }
}
match self.root {
    Some(ref mut rootnode) => SortedContainer::node_insert(n, rootnode),
    None => self.root = Some(Box::new(n)),
}