rust学习笔记16-206.反转链表(递归)

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,最后递归直到为空返回

相关推荐
南♡黎(・ิϖ・ิ)っ1 分钟前
JavaEE初阶,文件IO(2)
java·笔记·java-ee
野老杂谈28 分钟前
如何快速学习智能合约开发语言 Solidity
开发语言·学习·智能合约·solidity·以太坊·区块链开发
Han.miracle38 分钟前
Java线程的学习—多线程(一)
java·开发语言·学习
是店小二呀41 分钟前
Trilium非线性笔记测评:本地知识库+远程协作,构建你的第二大脑!
笔记
忧郁奔向冷的天43 分钟前
视觉SLAM十四讲2nd—学习笔记(二)20250817
笔记·学习
水蓝烟雨1 小时前
0430. 扁平化多级双向链表
数据结构·链表
立志成为大牛的小牛2 小时前
数据结构——三十一、最小生成树(王道408)
数据结构·学习·程序人生·考研·算法
摇滚侠2 小时前
Spring Boot3零基础教程,Actuator 导入,笔记82
java·spring boot·笔记
WarPigs2 小时前
Blender动画笔记
笔记·blender
Every exam must be3 小时前
10.27 JS学习12
开发语言·javascript·学习