我正在尝试在Rust中实现一个简单的二叉搜索树,但我很难确定插入节点的问题。我正在使用以下数据结构和功能。
enum BinaryTree<T> {
Leaf(T),
Branch(T, Box<BinaryTree<T>>, Box<BinaryTree<T>>),
Null,
}
fn createBinarySearchTree(vector: Vec<int>) -> BinaryTree<int> {
fn insertNode(val: int, btree: &BinaryTree<int>) -> BinaryTree<int> {
match btree {
&Leaf(tval) if val > tval => Branch(tval, box Null, box Leaf(val)),
&Leaf(tval) if val < tval => Branch(tval, box Leaf(val), box Null),
&Branch(tval, box ref left, box ref right) if val > tval => insertNode(val,right),
&Branch(tval, box ref left, box ref right) if val < tval => insertNode(val,left),
&Null => Leaf(val),
&Leaf(lval) if val == lval => Leaf(val),
&Branch(lval, box ref left, box ref right) if val == lval => fail!("already has a node with {}", lval),
_ => Null,
}
}
let mut tree = Null;
for v in vector.iter() {
tree = insertNode(*v, &tree);
}
let immuTree = tree;
immuTree
}
fn printTree(tree: &BinaryTree<int>) {
fn innerPrint(prefix: &str, tree: &BinaryTree<int>, level: int) {
let lvDesc = format!("lv {}", level);
match tree {
&Leaf(val) => println!("{}-{} leaf: {}", lvDesc, prefix, val),
&Branch(val, box ref left, box ref right) => {
println!("{}-{} node: {}", lvDesc, prefix, val);
innerPrint("left branch <-", left, level + 1);
innerPrint("right branch ->", right, level + 1);
},
&Null => println!("end"),
}
}
innerPrint("root", tree, 0);
}
在调用printTree(&createBinarySearchTree(vec![43,2,45,7,72,28,34,33]))
时,树只打印出33,34
,不幸的是我无法调试,因为使用调试信息进行编译会导致编译器错误。此外,当我在插入时在分支上匹配时,我试图返回一个分支,但这需要我克隆叶子/给予所有权的方式,我只是无法绕过我的脑袋。所以任何帮助都会非常感激
干杯
答案 0 :(得分:1)
我相信这些分支是错的:
&Branch(tval, box ref left, box ref right) if val > tval => insertNode(val, right),
&Branch(tval, box ref left, box ref right) if val < tval => insertNode(val, left),
由于您正在改变原始树,因此每个分支都会丢失原始树根。假设修复(未经测试):
&Branch(tval, box ref left, box ref right) if val > tval => Branch(tval, left, insertNode(val, right)),
&Branch(tval, box ref left, box ref right) if val < tval => Branch(tval, insertNode(val, left), right),
修改强>
这个想法是正确的,但是你是正确的,Rust抱怨要离开&amp;一个模式守卫背后的指针,所以我不得不在里面做另一场比赛(结果更好)。我也无法忽略命名,所以我按照Rust编码风格清理它:
use std::fmt::Show;
enum BinaryTree<T> {
Leaf(T),
Branch(T, Box<BinaryTree<T>>, Box<BinaryTree<T>>),
Null,
}
fn create_binary_search_tree(vector: Vec<int>) -> BinaryTree<int> {
fn insert_node<T: Copy + Ord + Show>(val: T, btree: BinaryTree<T>) -> BinaryTree<T> {
match btree {
Leaf(tval) if val > tval => Branch(tval, box Null, box Leaf(val)),
Leaf(tval) if val < tval => Branch(tval, box Leaf(val), box Null),
Branch(tval, left, right) => match val.cmp(&tval) {
Greater => Branch(tval, left, box insert_node(val, *right)),
Less => Branch(tval, box insert_node(val, *left), right),
Equal => fail!("already has a node with {}", tval),
},
Null => Leaf(val),
Leaf(lval) if val == lval => Leaf(val),
_ => Null,
}
}
let mut tree = Null;
for v in vector.iter() {
tree = insert_node(*v, tree);
}
let immuTree = tree;
immuTree
}
fn print_tree(tree: &BinaryTree<int>) {
fn inner_print(prefix: &str, tree: &BinaryTree<int>, level: int) {
let lvDesc = format!("lv {}", level);
match tree {
&Leaf(val) => println!("{}-{} leaf: {}", lvDesc, prefix, val),
&Branch(val, box ref left, box ref right) => {
println!("{}-{} node: {}", lvDesc, prefix, val);
inner_print("left branch <-", left, level + 1);
inner_print("right branch ->", right, level + 1);
},
&Null => println!("end"),
}
}
inner_print("root", tree, 0);
}
fn main() {
print_tree(&create_binary_search_tree(vec![43, 2, 45, 7, 72, 28, 34, 33]));
}
我验证此代码适用于“http://play.rust-lang.org/”