【发布时间】:2020-12-07 06:23:19
【问题描述】:
我正在尝试在 Rust 中实现红黑树。经过2天与编译器的斗争,我准备放弃并在这里寻求帮助。
这个问题对我帮助很大:How do I handle/circumvent "Cannot assign to ... which is behind a & reference" in Rust?
我查看了 Rust 中 RB-Trees 的现有示例代码,但我看到的所有示例代码都使用了某种形式的不安全操作或 null,我们不应该在这里使用。
我有以下代码:
#[derive(Debug, Clone, PartialEq)]
pub enum Colour {
Red,
Black,
}
type T_Node<T> = Option<Box<Node<T>>>;
#[derive(Debug, Clone, PartialEq)]
pub struct Node<T: Copy + Clone + Ord> {
value: T,
colour: Colour,
parent: T_Node<T>,
left: T_Node<T>,
right: T_Node<T>,
}
impl<T: Copy + Clone + Ord> Node<T>
{
pub fn new(value: T) -> Node<T>
{
Node {
value: value,
colour: Colour::Red, // add a new node as red, then fix violations
parent: None,
left: None,
right: None,
// height: 1,
}
}
pub fn insert(&mut self, value: T)
{
if self.value == value
{
return;
}
let mut leaf = if value < self.value { &mut self.left } else { &mut self.right };
match leaf
{
None =>
{
let mut new_node = Node::new(value);
new_node.parent = Some(Box::new(self));
new_node.colour = Colour::Red;
(*leaf) = Some(Box::new(new_node));
},
Some(ref mut leaf) =>
{
leaf.insert(value);
}
};
}
}
new_node.parent = Some(Box::new(self)); 行给了我错误。
我理解为什么会发生错误(self 被声明为可变引用)并且我不知道如何解决这个问题,但我需要 self 成为可变引用以便我可以修改我的树(除非你可以建议更好的东西)。
我尝试将 T_Node 声明为具有可变引用,而不仅仅是 Node,但这只会产生更多问题。
我也愿意接受关于更好地选择变量类型的建议。
感谢任何帮助。
【问题讨论】:
-
您可以创建一个根结构,就像链接帖子中的
LinkedList结构一样。这样你就不需要交换self,只需要交换self.start。 -
哦,我的错,我没有看到你在哪里引用父节点。这是一个与所有权规则不符的设计(因为现在一个节点由它的父节点和子节点共同拥有)。在这里您可以找到一些双链表的解决方法:stackoverflow.com/questions/22268861/… rust-unofficial.github.io/too-many-lists/index.html 也可能是在 rust 中构建新集合类型的有趣介绍
-
我希望这最终归结为 this question 的副本,因为
left.parent和right.parent都循环回self
标签: rust red-black-tree-insertion