解决红黑树实施中的生命周期冲突

问题描述

我一直在尝试在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 (将#修改为@)