Tree 有没有一种方法可以在可变树上迭代以获得随机节点?
我正在尝试更新树结构的节点。随机选择要更新的节点。要使用库采样算法对树中的节点进行采样,我必须对节点进行迭代,因此我尝试为我的Tree 有没有一种方法可以在可变树上迭代以获得随机节点?,tree,rust,Tree,Rust,我正在尝试更新树结构的节点。随机选择要更新的节点。要使用库采样算法对树中的节点进行采样,我必须对节点进行迭代,因此我尝试为我的节点枚举制作一个迭代器 问题是,一方面,我必须在堆栈或队列中存储子节点的引用,但另一方面,我必须返回父节点的可变引用。Rust不允许为一个值创建多个可变引用,也不允许将不可变引用转换为可变引用 有没有一种方法可以迭代可变树?或者有没有其他方法可以随机获取树中节点的可变引用 这是我的密码 #![feature(box_syntax, box_patterns)] exter
节点
枚举制作一个迭代器
问题是,一方面,我必须在堆栈或队列中存储子节点的引用,但另一方面,我必须返回父节点的可变引用。Rust不允许为一个值创建多个可变引用,也不允许将不可变引用转换为可变引用
有没有一种方法可以迭代可变树?或者有没有其他方法可以随机获取树中节点的可变引用
这是我的密码
#![feature(box_syntax, box_patterns)]
extern crate rand;
// Simple binary tree structure
#[derive(Debug)]
enum Node {
Leaf(u8),
Branch(Box<Node>, Box<Node>),
}
impl Node {
fn iter_mut(&mut self) -> IterMut {
IterMut {
stack: vec![self],
}
}
fn pick_random_node_mut<'a>(&'a mut self) -> &'a mut Node {
// Revervoir sampling
let rng = &mut rand::thread_rng();
rand::seq::sample_iter(rng, self.iter_mut(), 1)
.ok().and_then(|mut v| v.pop()).unwrap()
}
}
// An iterator for `Node`
struct IterMut<'a> {
stack: Vec<&'a mut Node>,
}
impl <'a> Iterator for IterMut<'a> {
type Item = &'a mut Node;
fn next(&mut self) -> Option<&'a mut Node> {
let node = self.stack.pop()?;
// I am stucking here: cannot borrow `*node` as mutable more than once at a time
if let &mut Node::Branch(box ref mut a, box ref mut b) = node {
self.stack.push(b);
self.stack.push(a);
}
Some(node)
}
}
fn main() {
use Node::*;
let mut tree: Node = Branch(box Leaf(1), box Leaf(2));
println!("{:?}", tree);
{
let node: &mut Node = tree.pick_random_node_mut();
*node = Leaf(3);
}
println!("{:?}", tree);
}
#![功能(方框语法、方框模式)]
外部板条箱;
//简单二叉树结构
#[导出(调试)]
枚举节点{
叶(u8),
分支(盒子,盒子),
}
impl节点{
fn iter_mut(&mut self)->IterMut{
伊特穆特{
堆栈:vec![self],
}
}
fn拾取随机节点和多个节点{
//混响采样
设rng=&mut rand::thread_rng();
rand::seq::sample_iter(rng,self.iter_mut(),1)
.好的().然后(| mut v | v.pop()).展开()
}
}
//'节点的迭代器`
结构IterMut,
}
恳求{
类型Item=&'a mut节点;
fn next(&mut self)->OptionNo,为树的节点编写可变引用的迭代器是不安全的
假设我们有这样的树结构:
+-+
+----+ +----+
| +-+ |
| |
| |
+--v-+--v--+
| 50 | | 100 |
+----+ +-----+
如果存在这样的迭代器,我们可以这样称呼它:
let mut all_nodes: Vec<&mut Node> = tree.iter_mut().collect();
现在,x
和y
是彼此可变的别名。在完全安全的代码中,违反了基本的生锈要求。这就是为什么这样的迭代器是不可能的
您可以实现对树中值的可变引用的迭代器:
impl<'a> Iterator for IterMut<'a> {
type Item = &'a mut u8;
fn next(&mut self) -> Option<Self::Item> {
loop {
let node = self.stack.pop()?;
match node {
Node::Branch(a, b) => {
self.stack.push(b);
self.stack.push(a);
}
Node::Leaf(l) => return Some(l),
}
}
}
}
请你解释一下为什么它不同于像你的堆栈那样的可变引用集合
本身不是一个好主意。你可以很容易地得到可变别名,这在Rust中是不允许的。
impl<'a> Iterator for IterMut<'a> {
type Item = &'a mut u8;
fn next(&mut self) -> Option<Self::Item> {
loop {
let node = self.stack.pop()?;
match node {
Node::Branch(a, b) => {
self.stack.push(b);
self.stack.push(a);
}
Node::Leaf(l) => return Some(l),
}
}
}
}
{
let rando = match rand::seq::sample_iter(&mut rand::thread_rng(), tree.iter_mut(), 1) {
Ok(mut v) => v.pop().unwrap(),
Err(_) => panic!("Not enough elements"),
};
*rando += 1;
}