这是我用来表示单个链接列表的数据结构:
type Link = Option<Box<Node>>;
pub struct Node {
elem: i32,
next: Link,
}
我想实现一种从列表末尾删除第N个节点的方法:
// Original list
A -> B -> C -> D -> None
// remove 1 from the end of the original list
A -> B -> C -> None
// Remove 2 from the end of the original list
A -> B -> D -> None
我一直在和借位检查员打架:
fn remove_nth_node_from_end(list: &mut Link, n: usize) {
if list.is_none() {
return;
}
let mut i = 0;
let mut fast = list;
while let Some(ref mut node) = {fast} {
if i == n {
break;
}
i += 1;
fast = &mut node.next;
}
// issues start here, since I need to mutably borrow
// the list (and it has already been moved above for fast)
// but without moving I have troubles implementing the above loop
let mut slow = &mut list;
// iterate over the list using slow and fast
// when fast is None
// slow.next = slow.next.next
}
error[E0596]: cannot borrow immutable argument `list` as mutable
--> src/lib.rs:25:25
|
25 | let mut slow = &mut list;
| ^^^^ cannot borrow mutably
help: consider removing the `&mut`, as it is an immutable binding to a mutable reference
|
25 | let mut slow = list;
| ^^^^
error[E0382]: use of moved value: `list`
--> src/lib.rs:25:25
|
13 | let mut fast = list;
| -------- value moved here
...
25 | let mut slow = &mut list;
| ^^^^ value used here after move
|
= note: move occurs because `list` has type `&mut std::option::Option<std::boxed::Box<Node>>`, which does not implement the `Copy` trait
如何实现方法的其余部分?
请注意,我的方法不采用self
作为参数,并且列表参数至少需要在当前实现中移动两次。
答案 0 :(得分:0)
这是不使用递归即可编写方法的方式。
fn remove_nth(list: &mut Link, n: usize) {
if list.is_none() {
return;
}
let get_length = |l: &Link| {
let mut length = 0;
let mut current = l;
while let Some(n) = {current} {
length += 1;
current = &n.next;
}
length
};
let length = get_length(list);
let mut i = 0;
let mut current = list;
while i < length - n {
if let Some(link) = {current} {
current = &mut link.next;
} else {
panic!("Invalid node!");
}
i += 1;
}
*current = current.as_mut().unwrap().next.take();
}
不幸的是,我没有通过使用更高效的运行器模式来使借阅检查器满意。