- Gaukler
- Oct 9, 2012
-
|
I'm trying to learn some Rust since it seems like a pretty rad idea, so far I've been trying to do some simple data structures to figure it all out.
Here's what I have for a binary search tree, it compiles and runs but the insertion doesn't fully work -- it seems to remove all the past changes each time you insert a new node:
http://is.gd/qhiZkq
code:fn main() {
let mut butt = BSTNode::new(5);
println!("{:?}", butt);
butt.insert(7);
println!("{:?}", butt);
butt.insert(2);
println!("{:?}", butt);
butt.insert(1);
butt.insert(3);
butt.insert(4);
butt.insert(6);
butt.insert(8);
println!("{:?}", butt);
}
#[derive(Debug)]
struct BSTNode {
value: i32,
left: Option<Box<BSTNode>>,
right: Option<Box<BSTNode>>
}
impl BSTNode {
fn new(value: i32) -> BSTNode {
BSTNode {
value: value,
left: None,
right: None
}
}
fn insert(&mut self, value: i32) {
match (self.value > value, self.left.take(), self.right.take()) {
(true, None, _) => self.left = Some(Box::new(BSTNode::new(value))),
(true, Some(ref mut left), _) => left.insert(value),
(false, _, None) => self.right = Some(Box::new(BSTNode::new(value))),
(false, _, Some(ref mut right)) => right.insert(value),
}
}
}
Which prints:
code:BSTNode { value: 5, left: None, right: None }
BSTNode { value: 5, left: None, right: Some(BSTNode { value: 7, left: None, right: None }) }
BSTNode { value: 5, left: Some(BSTNode { value: 2, left: None, right: None }), right: None }
BSTNode { value: 5, left: None, right: None }
Anyone know how I screwed up?
Also how far off base is everything I did idiomatically-wise?
Also what exactly is 'self.left.take()' doing? It fails compiling without it with the message 'cannot move out of borrowed content' and I somehow googled my way in to using it.
edit: alright well scratch why it doesn't work, take() just replaces the content with a None, which is why my children are disappearing. How do I borrow the self.left and self.right in the match otherwise?
I'm quite new to Rust myself so I spent some time wrestling the borrow checker, but the following works: (http://is.gd/nVAEU0)
code:fn main() {
let mut butt = BSTNode::new(5);
println!("{:?}", butt);
butt.insert(7);
println!("{:?}", butt);
butt.insert(2);
println!("{:?}", butt);
butt.insert(1);
butt.insert(3);
butt.insert(4);
butt.insert(6);
butt.insert(8);
println!("{:?}", butt);
}
#[derive(Debug)]
struct BSTNode {
value: i32,
left: Option<Box<BSTNode>>,
right: Option<Box<BSTNode>>
}
impl BSTNode {
fn new(value: i32) -> BSTNode {
BSTNode {
value: value,
left: None,
right: None
}
}
fn insert(&mut self, value: i32) {
if self.value > value {
match self.left {
Some(ref mut left) => left.insert(value),
None => self.left = Some(Box::new(BSTNode::new(value))),
}
} else {
match self.right {
Some(ref mut right) => right.insert(value),
None => self.right = Some(Box::new(BSTNode::new(value))),
}
}
}
}
Prints:
code:BSTNode { value: 5, left: None, right: None }
BSTNode { value: 5, left: None, right: Some(BSTNode { value: 7, left: None, right: None }) }
BSTNode { value: 5, left: Some(BSTNode { value: 2, left: None, right: None }), right: Some(BSTNode { value: 7, left: None, right: None }) }
BSTNode { value: 5, left: Some(BSTNode { value: 2, left: Some(BSTNode { value: 1, left: None, right: None }), right: Some(BSTNode { value: 3, left: None, right: Some(BSTNode { value: 4, left: None, right: None }) }) }), right: Some(BSTNode { value: 7, left: Some(BSTNode { value: 6, left: None, right: None }), right: Some(BSTNode { value: 8, left: None, right: None }) }) }
Which looks right by my checking. I THINK the problem was when you do (self.value > value, self.left, self.right), you implicitly create a new Tuple which borrows self.left and self.right, so you can't use them in your match arms.
|
#
¿
Jun 19, 2015 17:36
|
|
- Adbot
-
ADBOT LOVES YOU
|
|
#
¿
Apr 29, 2024 19:09
|
|