rust函数递归在14中已经提到,接下来我们把206.反转链表,用递归法实现
递归函数通常包含两个主要部分:
基准条件(Base Case):递归终止的条件,避免无限递归。
递归步骤(Recursive Step):将问题分解为更小的子问题,并调用自身来解决这些子问题。
rust
//Definition for singly-linked list.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>
}
impl ListNode {
#[inline]
fn new(val: i32) -> Self {
ListNode {
next: None,
val
}
}
}
pub fn reverse(mut pre : Option<Box<ListNode>>,mut cur : Option<Box<ListNode>>) -> Option<Box<ListNode>> {
if let Some(mut node) = cur.take() {
//如果不为空使用temp先保存node.next, 然后让node.next指向pre
let mut temp = node.next;
node.next = pre;
//递归调用
return reverse(Some(node), temp);
} else {
pre
}
}
pub fn reverse_list(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut pre: Option<Box<ListNode>> = None;
return reverse(pre, head);
}
// 辅助函数:打印链表内容不转移所有权
fn print_list(head: Option<&Box<ListNode>>) {
match head {
Some(node) => {
let mut current = Some(node); // 初始化当前节点指针
while let Some(node) = current {
print!("{} -> ", node.val);
current = node.next.as_ref(); // 使用 as_ref() 获取对 next 的引用
}
println!("None");
}
None => {
println!("链表为空");
}
}
}
// 函数:将 i32 数组转换为链表并返回头节点
fn array_to_list(arr: Vec<i32>) -> Option<Box<ListNode>> {
let mut head: Option<Box<ListNode>> = None;
let mut current: &mut Option<Box<ListNode>> = &mut head;
for &val in arr.iter().rev() { // 从后往前构建链表
let new_node = Box::new(ListNode {
val,
next: current.take(), // 取出当前节点并设置为新节点的 next
});
*current = Some(new_node); // 更新当前节点
current = &mut head; // 指向头节点
}
head
}
fn main() {
let arr = vec![1, 2, 3, 4, 5];
// 调用函数创建链表
let head = array_to_list(arr);
// 打印链表
print_list(head.as_ref()); // 使用 as_ref() 避免转移所有权
let node = reverse_list(head);
print_list(node.as_ref());
}
总结,用递归首先需要确定终止条件,在翻转链表中,终止条件就是cur为空,然后返回pre, 如果不为空先保存node.next(cur.next)到临时变量temp中,然后node.next=pre,最后递归直到为空返回