I am trying to implement a double linked binary tree in rust, and I have some problems when I try to implement functions to return a specific value from a node to replace it in a node that contain the value that I want to delete. This is my code :
use std::{borrow::BorrowMut, cell::RefCell, fmt::Debug, rc::Rc};
#[derive(Debug)]
struct Tree<T> {
root: Link<T>
}
type Link<T> = Option<Rc<RefCell<Node<T>>>>;
#[derive(Debug)]
struct Node<T> {
value: T,
prev: Link<T>,
right: Link<T>,
left: Link<T>
}
impl<T: Ord+ Debug> Node<T> {
fn new(value: T, prev: Link<T>, right: Link<T>, left: Link<T>) -> Self {
Node {
value: value,
prev: prev,
right: right,
left: left
}
}
//fn get_prev(&mut self, value: &T) -> Link<T> {
//if value > &self.value {
//return self.right.clone();
//}else {
//return self.left.clone();
//}
//}
fn insert_value(&mut self, value: T, prev: Link<T>) {
if value == self.value { return; }
if value > self.value {
if self.right.is_none() {
let mut node = Some(Rc::new(RefCell::new(Node::new(value, prev, None, None))));
self.right = node;
}else {
let mut prev_current = self.right.clone();
self.right.as_mut().map(|node| {
(**node).borrow_mut().insert_value(value, prev_current);
});
}
}else {
if self.left.is_none() {
let mut node = Some(Rc::new(RefCell::new(Node::new(value, prev, None, None))));
self.left = node;
}else {
let mut prev_current = self.left.clone();
self.left.as_mut().map(|node| {
(**node).borrow_mut().insert_value(value, prev_current);
});
}
}
}
fn print_prev(&self){
println!("{:?}", self.value);
}
fn print_tree(&self) {
println!("------");
println!("{:?}", self.value);
if (!self.prev.is_none()){
self.prev.as_ref().map(|node| {
(**node).borrow().print_prev();
});
}
if (!self.right.is_none()) {
self.right.as_ref().map(|node| {
(**node).borrow().print_tree();
});
}
if (!self.left.is_none()) {
self.left.as_ref().map(|node| {
(**node).borrow().print_tree();
});
}
}
fn set_prev_none(&mut self, value: &T) {
if value > &self.value {
self.right = None;
}else {
self.left = None;
}
}
fn set_prev_node(&mut self, value: &T, node: Link<T>){
if value > &self.value {
self.right = node;
}else {
self.left = node;
}
}
fn find_left_none(&mut self) -> T {
if (self.left.is_none() && self.right.is_none()) {
let mut value = &self.value;
self.prev.as_mut().map(|node| {
(**node).borrow_mut().set_prev_none(value);
});
return self.value;
}else {
return (**self.left.as_mut().unwrap().borrow_mut()).borrow_mut().find_left_none();
}
}
fn delete_node(&mut self, value: T) {
if self.value == value {
if self.right.is_none() && self.left.is_none() {
let mut temp_val = &self.value;
self.prev.as_mut().map(|node| {
(**node).borrow_mut().set_prev_none(temp_val);
});
}else if(self.right.is_none() ^ self.left.is_none()) {
let mut prev_temp = self.prev.clone();
let mut temp_val = &self.value;
let mut temp_next = None;
if self.right.is_none(){
temp_next = self.right.clone();
self.right.as_mut().map(|node| {
(**node).borrow_mut().prev = prev_temp.clone();
});
}else {
temp_next = self.left.clone();
self.left.as_mut().map(|node| {
(**node).borrow_mut().prev = prev_temp.clone();
});
}
prev_temp.as_mut().map(|node| {
(**node).borrow_mut().set_prev_node(temp_val, temp_next);
});
}else {
let mut val: Option<T> = None;
self.right.as_mut().map(|node| {
val = Some((**node).borrow_mut().find_left_none());
});
self.value = val.unwrap();
}
}else {
if value > self.value {
self.right.as_mut().map(|node| {
(**node).borrow_mut().delete_node(value);
});
}else {
self.left.as_mut().map(|node| {
(**node).borrow_mut().delete_node(value);
});
}
}
}
}
impl<T: Ord+Debug> Tree<T> {
fn new() -> Self {
Tree {
root: None
}
}
fn insert_value(&mut self, value: T) {
if self.root.is_none() {
self.root = Some(Rc::new(RefCell::new(Node::new(value, None, None, None))));
}else {
let mut prev = self.root.clone();
self.root.as_mut().map(|node| {
(**node).borrow_mut().insert_value(value, prev);
});
}
}
fn delete_node(&mut self, value: T){
if !self.root.is_none() {
self.root.as_mut().map(|node| {
(**node).borrow_mut().delete_node(value);
});
}
}
fn print_tree(&self) {
if !self.root.is_none() {
self.root.as_ref().map(|node| {
(**node).borrow().print_tree();
});
}else {
println!("empty");
}
}
}
fn main() {
let mut tree = Tree::new();
tree.insert_value(5);
tree.insert_value(1);
tree.insert_value(7);
tree.insert_value(4);
tree.insert_value(5);
tree.print_tree();
}
This is the error:
error[E0507]: cannot move out of `self.value` which is behind a mutable reference
--> .\tree-double.rs:107:20
|
107 | return self.value;
| ^^^^^^^^^^ move occurs because `self.value` has type `T`, which does not implement the `Copy` trait
How I can return the value or clone it?
use std::{borrow::BorrowMut, cell::RefCell, fmt::Debug, rc::Rc};
#[derive(Debug)]
struct Tree<T: Clone> {
root: Link<T>,
}
type Link<T> = Option<Rc<RefCell<Node<T>>>>;
// you can restrict T to be Cloneable
#[derive(Debug)]
struct Node<T: Clone> {
value: T,
prev: Link<T>,
right: Link<T>,
left: Link<T>,
}
impl<T: Ord + Debug + Clone> Node<T> {
fn new(value: T, prev: Link<T>, right: Link<T>, left: Link<T>) -> Self {
Node {
value: value,
prev: prev,
right: right,
left: left,
}
}
//fn get_prev(&mut self, value: &T) -> Link<T> {
//if value > &self.value {
//return self.right.clone();
//}else {
//return self.left.clone();
//}
//}
fn insert_value(&mut self, value: T, prev: Link<T>) {
if value == self.value {
return;
}
if value > self.value {
if self.right.is_none() {
let mut node = Some(Rc::new(RefCell::new(Node::new(value, prev, None, None))));
self.right = node;
} else {
let mut prev_current = self.right.clone();
self.right.as_mut().map(|node| {
(**node).borrow_mut().insert_value(value, prev_current);
});
}
} else {
if self.left.is_none() {
let mut node = Some(Rc::new(RefCell::new(Node::new(value, prev, None, None))));
self.left = node;
} else {
let mut prev_current = self.left.clone();
self.left.as_mut().map(|node| {
(**node).borrow_mut().insert_value(value, prev_current);
});
}
}
}
fn print_prev(&self) {
println!("{:?}", self.value);
}
fn print_tree(&self) {
println!("------");
println!("{:?}", self.value);
if (!self.prev.is_none()) {
self.prev.as_ref().map(|node| {
(**node).borrow().print_prev();
});
}
if (!self.right.is_none()) {
self.right.as_ref().map(|node| {
(**node).borrow().print_tree();
});
}
if (!self.left.is_none()) {
self.left.as_ref().map(|node| {
(**node).borrow().print_tree();
});
}
}
fn set_prev_none(&mut self, value: &T) {
if value > &self.value {
self.right = None;
} else {
self.left = None;
}
}
fn set_prev_node(&mut self, value: &T, node: Link<T>) {
if value > &self.value {
self.right = node;
} else {
self.left = node;
}
}
fn find_left_none(&mut self) -> T {
if (self.left.is_none() && self.right.is_none()) {
let mut value = &self.value;
self.prev.as_mut().map(|node| {
(**node).borrow_mut().set_prev_none(value);
});
// you need clone the value before return, otherwise T must implement Copy trait, because
return self.value.clone();
} else {
return (**self.left.as_mut().unwrap().borrow_mut())
.borrow_mut()
.find_left_none();
}
}
fn delete_node(&mut self, value: T) {
if self.value == value {
if self.right.is_none() && self.left.is_none() {
let mut temp_val = &self.value;
self.prev.as_mut().map(|node| {
(**node).borrow_mut().set_prev_none(temp_val);
});
} else if (self.right.is_none() ^ self.left.is_none()) {
let mut prev_temp = self.prev.clone();
let mut temp_val = &self.value;
let mut temp_next = None;
if self.right.is_none() {
temp_next = self.right.clone();
self.right.as_mut().map(|node| {
(**node).borrow_mut().prev = prev_temp.clone();
});
} else {
temp_next = self.left.clone();
self.left.as_mut().map(|node| {
(**node).borrow_mut().prev = prev_temp.clone();
});
}
prev_temp.as_mut().map(|node| {
(**node).borrow_mut().set_prev_node(temp_val, temp_next);
});
} else {
let mut val: Option<T> = None;
self.right.as_mut().map(|node| {
val = Some((**node).borrow_mut().find_left_none());
});
self.value = val.unwrap();
}
} else {
if value > self.value {
self.right.as_mut().map(|node| {
(**node).borrow_mut().delete_node(value);
});
} else {
self.left.as_mut().map(|node| {
(**node).borrow_mut().delete_node(value);
});
}
}
}
}
impl<T: Ord + Debug + Clone> Tree<T> {
fn new() -> Self {
Tree { root: None }
}
fn insert_value(&mut self, value: T) {
if self.root.is_none() {
self.root = Some(Rc::new(RefCell::new(Node::new(value, None, None, None))));
} else {
let mut prev = self.root.clone();
self.root.as_mut().map(|node| {
(**node).borrow_mut().insert_value(value, prev);
});
}
}
fn delete_node(&mut self, value: T) {
if !self.root.is_none() {
self.root.as_mut().map(|node| {
(**node).borrow_mut().delete_node(value);
});
}
}
fn print_tree(&self) {
if !self.root.is_none() {
self.root.as_ref().map(|node| {
(**node).borrow().print_tree();
});
} else {
println!("empty");
}
}
}
fn main() {
let mut tree = Tree::new();
tree.insert_value(5);
tree.insert_value(1);
tree.insert_value(7);
tree.insert_value(4);
tree.insert_value(5);
tree.print_tree();
}
as you define the return value of find_left_none to T which is not a reference type, you have to clone the value before return from the method
The problem here is that you're trying to destroy part of the node, but you only have a mutable reference to it. Either self.value
must be able to be moved (which means the entire struct is now "dead" (if part of it moves, the whole thing is gone) and thus you need to pass self
to the function not &mut self
to do that) or the value
field must be able to be copied ( Copy
trait, and a constraint on what you can hold).
So are you trying to destroy the current node when you return the contents? By context, probably not, it seems like you want the value
of the node returned, hence T
being the return value. So you either need to explicitly std::clone
it, or you need to return a reference to it, which means lifetimes.
I suggest reading through Learn Rust With Entirely Too Many Linked Lists for inspiration and assistance. In particular, the firstPop chapter, as well as the lifetimes one in Iter
For your program, change the following:
impl<T: Clone + Ord + Debug> Node<T> {
// Snip
fn find_left_none(&mut self) -> T {
if (self.left.is_none() && self.right.is_none()) {
let mut value = &self.value;
self.prev.as_mut().map(|node| {
(**node).borrow_mut().set_prev_none(value);
});
return self.value.clone();
}else {
return (**self.left.as_mut().unwrap().borrow_mut()).borrow_mut().find_left_none();
}
}
// Snip
impl<T: Clone + Ord+Debug> Tree<T> {
I hope that helps explain what else you needed and why.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.