Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何正确地插入生锈的AVL树?_Rust_Avl Tree_Ownership - Fatal编程技术网

Rust 如何正确地插入生锈的AVL树?

Rust 如何正确地插入生锈的AVL树?,rust,avl-tree,ownership,Rust,Avl Tree,Ownership,我对锈病很陌生,我正在尝试创建一棵AVL树。我使用Rc是因为我希望每个节点都由它上面的节点拥有,并且RefCell使它在内部是可变的 我已经开始构建“insert”方法,但它并没有在正确的位置插入新节点,而是用新节点替换“root”节点,我很难理解为什么。我相信这可能是所有权问题,但我不确定 use std::cell::RefCell; use std::cmp::Ordering; use std::rc::Rc; #[derive(Debug)] pub struct BaseNode

我对锈病很陌生,我正在尝试创建一棵AVL树。我使用Rc是因为我希望每个节点都由它上面的节点拥有,并且RefCell使它在内部是可变的

我已经开始构建“insert”方法,但它并没有在正确的位置插入新节点,而是用新节点替换“root”节点,我很难理解为什么。我相信这可能是所有权问题,但我不确定

use std::cell::RefCell;
use std::cmp::Ordering;
use std::rc::Rc;

#[derive(Debug)]
pub struct BaseNode {
    pub key: u32,
    pub left: AvlTree,
    pub right: AvlTree,
}

pub type AvlNode = Rc<RefCell<BaseNode>>;
pub type AvlTree = Option<AvlNode>;

impl BaseNode {
    fn new(key: u32) -> Self {
        Self {
            key: key,
            left: None,
            right: None,
        }
    }
}

trait AvlNodeTrait {
    fn new_node(key: u32) -> Self;
}

impl AvlNodeTrait for AvlNode {
    fn new_node(key: u32) -> Self {
        Rc::new(RefCell::new(BaseNode::new(key)))
    }
}

pub trait AvlTreeTrait {
    fn new() -> Self;
    fn left(&self) -> Self;
    fn right(&self) -> Self;
    fn insert(&mut self, key: u32);
    fn dupe(&self) -> Self;
    fn set(&mut self, node: AvlNode);
}

impl AvlTreeTrait for AvlTree {
    fn new() -> Self {
        None
    }

    fn left(&self) -> Self {
        if let Some(node) = self {
            return node.borrow().right.dupe();
        }

        panic!("Trying to get Left of None!")
    }

    fn right(&self) -> Self {
        if let Some(node) = self {
            return node.borrow().right.dupe();
        }

        panic!("Trying to get right of None!")
    }

    fn dupe(&self) -> Self {
        match self {
            Some(node) => Some(Rc::clone(&node)),
            None => None,
        }
    }

    fn set(&mut self, node: AvlNode) {
        *self = Some(Rc::clone(&node));
    }

    fn insert(&mut self, key: u32) {
        let node = AvlNode::new_node(key);

        let mut curr_tree = self;
        let mut curr_key = 0;

        while !curr_tree.is_none() {
            if let Some(node) = &curr_tree {
                curr_key = node.borrow().key;

                if key > curr_key {
                    *curr_tree = curr_tree.left()
                } else if key < curr_key {
                    *curr_tree = curr_tree.right()
                } else {
                    return;
                }
            }
        }

        *curr_tree = Some(Rc::clone(&node));
    }
}

fn main() {
    let mut tree = AvlTree::new();
    println!("{:?}", tree); // None
    tree.insert(5);         
    println!("{:?}", tree); // Some(RefCell { value: BaseNode { key: 5, left: None, right: None } })
    tree.insert(56);        
    println!("{:?}", tree); // Some(RefCell { value: BaseNode { key: 2, left: None, right: None } })
}
使用std::cell::RefCell;
使用std::cmp::Ordering;
使用std::rc::rc;
#[导出(调试)]
发布结构BaseNode{
发布键:u32,
酒吧左:AvlTree,
酒吧右:AvlTree,
}
pub类型AvlNode=Rc;
发布类型AvlTree=选项;
impl基节点{
fn新(键:u32)->自{
自我{
钥匙:钥匙,
左:没有,
右:没有,
}
}
}
性状{
fn新节点(键:u32)->Self;
}
为AvlNode插入AvlNodeTrait{
fn新节点(键:u32)->Self{
Rc::new(RefCell::new(BaseNode::new(key)))
}
}
pub trait AvlTreeTrait{
fn new()->Self;
fn左(&self)->self;
fn右(和自)->self;
fn插入(&mut self,键:u32);
fn dupe(&self)->self;
fn集合(&mut self,节点:AvlNode);
}
为AvlTree执行AvlTreeTrait{
fn new()->Self{
没有一个
}
fn左(&self)->self{
如果让某些(节点)=自身{
return node.borrow().right.dupe();
}
惊慌失措!(“试图什么都不留下!”
}
fn右侧(&self)->self{
如果让某些(节点)=自身{
return node.borrow().right.dupe();
}
惊慌失措!(“试图纠正任何错误!”)
}
fn重复(和自我)->自我{
匹配自我{
Some(node)=>Some(Rc::clone(&node)),
无=>无,
}
}
fn集合(&mut self,节点:AvlNode){
*self=Some(Rc::clone(&node));
}
fn插入(&mut self,键:u32){
let node=AvlNode::新建_节点(键);
让mut curr_tree=self;
让mut curr_key=0;
while!curr_tree.is_none(){
如果让某些(节点)=&curr\u树{
curr_key=node.borrow().key;
如果键>当前键{
*curr_tree=curr_tree.left()
}否则,如果键<当前键{
*curr_tree=curr_tree.right()
}否则{
返回;
}
}
}
*curr_tree=Some(Rc::clone(&node));
}
}
fn main(){
让mut-tree=AvlTree::new();
println!(“{:?}”,树);//无
树。插入(5);
println!(“{:?}”,tree);//Some(RefCell{value:BaseNode{key:5,左:无,右:无})
插入(56);
println!(“{:?}”,tree);//Some(RefCell{value:BaseNode{key:2,左:无,右:无})
}

我想说,在这种情况下,使用RefCell是完全不必要的,而且可能是不安全的。RefCell将所有权/借用检查交给运行时,而不是在编译时进行。这可能会导致您的程序在违反任何借用规则时出现恐慌

我更喜欢像这样的“递归”类型:

struct AVLTree<T> {
    val: T,
    left: Option<Box<AVLTree<T>>>,
    right: Option<Box<AVLTree<T>>>
}
struct AVLTree{
瓦尔:T,
左:选项,
右:选项
}

这当然会由于内存分配而带来一些开销。

想象一下,只运行一次代码。您有(
self:&mut…
),您有curr\u tree=self。你知道当你运行
*curr\u tree=curr\u tree.left()
时结果是什么吗?你读过吗?在谈论生锈时,使用“不安全”时要小心,它有非常具体的含义
RefCell
使用起来并不不安全,正如您所注意到的,它们可以动态检测借用问题——这是一项功能——因此会延迟问题的诊断(如果有),这并不安全。请原谅我回答中的错误措辞。我应该去别的地方,因为我的意思不是“不安全”。我想说的是,对我来说,如果其他方法不起作用,RefCell是最后的选择。因为它很容易错过失败的案例,然后整个程序就崩溃了。没问题,我也同意你的担忧,以及作为最后手段使用的想法,我只想“修正”答案,以确保不会误导未来的读者。