如何读取和修改链接树中节点的值?

Posted

技术标签:

【中文标题】如何读取和修改链接树中节点的值?【英文标题】:How to read & modify value of node in linked tree? 【发布时间】:2020-08-23 04:29:03 【问题描述】:

我正在努力在 Rust 中实现树结构。 特别是获取和修改节点的值。使用该值的惯用方式是什么?

注意:实现是给定的,不能更改。

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

// Definition for a binary tree node.
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode 
  pub val: i32,
  pub left: Option<Rc<RefCell<TreeNode>>>,
  pub right: Option<Rc<RefCell<TreeNode>>>,


impl TreeNode 
  #[inline]
  pub fn new(val: i32) -> Self 
    TreeNode 
      val,
      left: None,
      right: None
    
  


fn main() 
    let mut root = Some(Rc::new(RefCell::new(TreeNode::new(1))));
    println!(":?", root.unwrap().borrow().val); // cannot infer type for type parameter `Borrowed`
    root.unwrap().get_mut().val = 2; // cannot borrow data in an `Rc` as mutable

【问题讨论】:

你有两个独立的问题。第一个描述here:root在调用unwrap()后被移动。第二个是因为您应该使用borrow_mut() 而不是get_mut()。后者使用典型的固有可变性而不是内部可变性。 为什么要把根包裹在RefCell、Rc和Option中?只需let mut root = TreeNode::new(1),然后填充分支 Rc&lt;RefCell&lt;TreeNode&gt;&gt; 表示节点可以由多个父节点共享。是这样吗?我希望树中的节点拥有他们的孩子,在Box&lt;TreeNode&gt; 说。 为什么是 Rc> 超出了问题的范围。实现已经给出,我一个字节都改不了。 @AlexLarionov 因为它在函数签名中。我得到 Option>>,而不是 TreeNode。 【参考方案1】:

如果您知道它是Some(T),则可以安全地unwrapRc&lt;T&gt; 应该像一个透明容器一样工作,在方法调用上取消引用,因此您通常可以将Rc&lt;T&gt; 视为T,或者在您的情况下特别是RefCell&lt;T&gt;,然后您可以与内部的值进行交互RefCell 使用 borrowborrow_mut 方法。示例:

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

// Definition for a binary tree node.
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode 
  pub val: i32,
  pub left: Option<Rc<RefCell<TreeNode>>>,
  pub right: Option<Rc<RefCell<TreeNode>>>,


impl TreeNode 
  #[inline]
  pub fn new(val: i32) -> Self 
    TreeNode 
      val,
      left: None,
      right: None
    
  



fn main() 
    let mut root = Some(Rc::new(RefCell::new(TreeNode::new(1))));
    let mut root = root.unwrap();
    println!(":?", root.borrow().val); // read access
    root.borrow_mut().val = 2; // write access

playground

另见Unwrap and access T from an Option<Rc<RefCell<T>>>

【讨论】:

【参考方案2】:
let root = Some(Rc::new(RefCell::new(TreeNode::new(1))));
let mut v = RefCell::borrow(root.as_ref().unwrap()).val) // Too verbose, but I do not know a brief way.
println!("", v); // 1
root.as_ref().unwrap().borrow_mut().val += 1;
v = RefCell::borrow(root.as_ref().unwrap()).val)
println!("", v); // 2

【讨论】:

以上是关于如何读取和修改链接树中节点的值?的主要内容,如果未能解决你的问题,请参考以下文章

二叉树:搜索树中的插入操作

如何在 html 树中向上移动一个节点并提取链接?

外部修改C#Winform程序配置文件后Winform程序通过ConfigurationManager.AppSettings.Get方法读取没有变化

java如何读取xml节点元素值?

671. 二叉树中第二小的节点

C#如何读取xml文件里面节点里面的属性信息?