问题描述
我一直在尝试在Rust中实现CLRS中的红黑树。代码(按目前的样子)如下:
use std::cmp::PartialOrd;
use std::fmt::display;
struct RedBlackNode<'a,T> {
elem: T,colour: bool,left: Option<&'a mut RedBlackNode<'a,T>>,right: Option<&'a mut RedBlackNode<'a,parent: Option<&'a mut RedBlackNode<'a,}
impl<'a,T> RedBlackNode<'a,T> {
fn new(elem: T) -> Self {
RedBlackNode::<T> {
elem: elem,colour: false,left: None,right: None,parent: None,}
}
}
impl<T: PartialEq> PartialEq for RedBlackNode<'_,T> {
fn eq(&self,other: &Self) -> bool {
self.elem == other.elem
}
}
pub struct RedBlackTree<'a,T> {
root: Option<RedBlackNode<'a,T: PartialOrd> RedBlackTree<'a,T> {
pub fn new() -> Self {
RedBlackTree::<T> { root: None }
}
pub fn add(&mut self,elem: T) {
let z: RedBlackNode<'a,T> = RedBlackNode::new(elem);
let mut y: Option<&'a mut RedBlackNode<'a,T>> = None;
let mut x: Option<&'a mut RedBlackNode<'a,T>> = self.root.as_mut();
while !x.is_none() {
y = x;
if z.elem < x.unwrap().elem {
x = x.unwrap().left;
} else {
x = x.unwrap().right;
}
}
z.parent = y;
if y.is_none() {
self.root = Some(z);
} else if z.elem < y.unwrap().elem {
y.unwrap().left = Some(&mut z);
} else {
y.unwrap().right = Some(&mut z);
}
z.left = None;
z.right = None;
z.colour = true;
self.insert_fixup(&mut z);
}
fn left_rotate(&mut self,z: &mut RedBlackNode<'a,T>) {
unimplemented!();
}
fn right_rotate(&mut self,T>) {
unimplemented!();
}
fn insert_fixup(&mut self,T>) {
if z.parent.is_none() {
return;
}
while z.parent.unwrap().colour {
if z.parent.unwrap().parent.is_some()
&& *z.parent.unwrap()
== *z.parent.unwrap().parent.unwrap().left.unwrap()
{
let y = z.parent.unwrap().parent.unwrap().right.unwrap();
if y.colour {
z.parent.unwrap().colour = false;
y.colour = false;
z.parent.unwrap().parent.unwrap().colour = true;
z = z.parent.unwrap().parent.unwrap();
} else {
if z.parent.unwrap().right.is_some()
&& *z == *z.parent.unwrap().right.unwrap()
{
z = z.parent.unwrap();
self.left_rotate(z);
}
z.parent.unwrap().colour = false;
z.parent.unwrap().parent.unwrap().colour = true;
self.right_rotate(z.parent.unwrap().parent.unwrap());
}
} else {
if z.parent.unwrap().parent.is_some()
&& *z.parent.unwrap()
== *z.parent.unwrap().parent.unwrap().right.unwrap()
{
let y = z.parent.unwrap().parent.unwrap().left.unwrap();
if y.colour {
z.parent.unwrap().colour = false;
y.colour = false;
z.parent.unwrap().parent.unwrap().colour = true;
z = z.parent.unwrap().parent.unwrap();
} else {
if z.parent.unwrap().left.is_some()
&& *z == *z.parent.unwrap().left.unwrap()
{
z = z.parent.unwrap();
self.right_rotate(z);
}
z.parent.unwrap().colour = false;
z.parent.unwrap().parent.unwrap().colour = true;
self.left_rotate(z.parent.unwrap().parent.unwrap());
}
}
}
}
self.root.unwrap().colour = false;
}
}
fn print_node<T>(node: &RedBlackNode<T>)
where
T: display,{
match &node.left {
Some(l) => print_node(l),None => {}
};
println!("{}",node.elem);
match &node.right {
Some(r) => print_node(r),None => {}
};
}
pub fn print_tree<T>(tree: &RedBlackTree<T>)
where
T: display,{
match &tree.root {
Some(root) => print_node(&root),None => {}
};
}
fn main() {
println!("Hello,world!");
let my_tree: RedBlackTree<u64> = RedBlackTree::new();
print_tree(&my_tree);
}
但是,由于第43行的生存期冲突,编译器会抱怨:
$ cargo run
Compiling rbtree v0.1.0 (/home/foo/bar/tmp/rbtree)
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:43:68
|
43 | let mut x: Option<&'a mut RedBlackNode<'a,T>> = self.root.as_mut();
| ^^^^^^
|
note: first,the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 39:5...
--> src/main.rs:39:5
|
39 | / pub fn add(&mut self,elem: T) {
40 | | let z: RedBlackNode<'a,T> = RedBlackNode::new(elem);
41 | |
42 | | let mut y: Option<&'a mut RedBlackNode<'a,T>> = None;
... |
69 | | self.insert_fixup(&mut z);
70 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:43:58
|
43 | let mut x: Option<&'a mut RedBlackNode<'a,T>> = self.root.as_mut();
| ^^^^^^^^^
note: but,the lifetime must be valid for the lifetime `'a` as defined on the impl at 34:6...
--> src/main.rs:34:6
|
34 | impl<'a,T> {
| ^^
note: ...so that the expression is assignable
--> src/main.rs:43:58
|
43 | let mut x: Option<&'a mut RedBlackNode<'a,T>> = self.root.as_mut();
| ^^^^^^^^^^^^^^^^^^
= note: expected `std::option::Option<&'a mut RedBlackNode<'a,T>>`
found `std::option::Option<&mut RedBlackNode<'a,T>>`
error: aborting due to prevIoUs error
For more information about this error,try `rustc --explain E0495`.
error: Could not compile `rbtree`.
To learn more,run the command again with --verbose.
我认为这是由于RedBlackTree<'a,T>
的定义获得了Option
类型(即第31行)内的根节点的所有权。
如何在不中断与RedBlackTree
的接口的情况下解决此问题?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)