leetcode简单题6 N.21 合并两个有序链表(对指针要有理解)rust描述

// [1,2,4]  [1,3,4] [1,1,2,3,4,4]
// [] [] []
// [] [0] [0]
//单向链表的定义。
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {//定义单向链表
    pub val: i32,//val表示当前节点值
    pub next: Option<Box<ListNode>>//next指向下一个节点
}

impl ListNode {//定义一个构造函数,方便创建节点
    #[inline]//inline表示内联,在编译时直接将函数代码插入到调用处
    fn new(val: i32) -> Self {//self表示当前结构体
        ListNode {//创建节点
            next: None,//默认为空
            val
        }
    }
}
//递归合并两个链表,返回那个取决于第一次比较,如果l1的val小于等于l2的val,则返回l1,否则返回l2,剩下的会递归比较,直到其中一个为空
pub fn merge_two_lists(
    list1: Option<Box<ListNode>>,
    list2: Option<Box<ListNode>>
) -> Option<Box<ListNode>> {
    match (list1, list2) {//递归合并两个链表
        (Some(mut l1), Some(mut l2)) => {//可变,后面函数的返回值不重要,都通过指针操作
            if l1.val < l2.val {//l1.val < l2.val表示l1的val小于l2的val
                l1.next = merge_two_lists(l1.next, Some(l2));//l1.next指向merge_two_lists(l1.next, Some(l2))
                Some(l1)//返回l1
            } else {
                l2.next = merge_two_lists(Some(l1), l2.next);
                Some(l2)//返回l2
            }
        },
        (Some(l1), None) => Some(l1),
        (None, Some(l2)) => Some(l2),//如果l1和l2有一个为空,则把另一个链表直接接在tail后面
        (None, None) => None,//两个链表都为空
    }
}
//迭代合并两个链表 , 一共有四个指针,分别指向两个链表,一个指针指向合并后的链表,一个指针指向合并后的链表的下一个节点
pub fn merge_two_lists2(
    list1: Option<Box<ListNode>>,
    list2: Option<Box<ListNode>>
) -> Option<Box<ListNode>> {

    let mut dummy = Box::new(ListNode::new(0));//创建虚拟头节点,最上层指针,指向合并后的链表
    let mut tail = &mut dummy;//tail指向虚拟头节点

    let (mut l1, mut l2) = (list1, list2);//l1和l2分别指向两个链表

    while l1.is_some() && l2.is_some() {//两个非空
        //l1和l2中较小的那个节点,作为当前节点的next
        if l1.as_ref().unwrap().val < l2.as_ref().unwrap().val {//as_ref().unwrap()表示解引用,即取出Option中的值 as_ref()表示将Option<&T>转换为Option<&U>,其中T和U是引用类型。
            tail.next = l1;//将l1的next指向tail
            tail = tail.next.as_mut().unwrap();//as_mut()表示将Option<&T>转换为Option<&mut T>,其中T是引用类型。
            l1 = tail.next.take();//take()表示将Option中的值取出,并置为None
        } else {//l2的val小于等于l1的val
            tail.next = l2;//tail.next指向l2
            tail = tail.next.as_mut().unwrap();//tail指向tail.next 因为要改next,所以需要可变,
            l2 = tail.next.take();// tail.next指向None l2指向原来的l2.next
        }
    }

    tail.next =
    if l1.is_some() {//前面已经判断了两个链表都不为空,所以l1和l2中至少有一个不为空 l1非空
        l1
    } else {//l2非空
        l2
    };//如果l1或者l2有一个为空,则把另一个链表直接接在tail后面

    dummy.next//返回虚拟头节点的next,即合并后的链表,跳过了虚拟头节点
}
fn main() {
    //根据测试用例 [1,2,4]  [1,3,4] [1,1,2,3,4,4]写断言
    let l1 = Some(Box::new(ListNode {
        val: 1,
        next: Some(Box::new(ListNode {
            val: 2,
            next: Some(Box::new(ListNode {
                val: 4,
                next: None,
            })),
        })),
    }));
    let l2 = Some(Box::new(ListNode {
        val: 1,
        next: Some(Box::new(ListNode {
            val: 3,
            next: Some(Box::new(ListNode {
                val: 4,
                next: None,
            })),
        })),
    }));
    //l1与l2合并后的结果
    let l3 = Some(Box::new(ListNode {
        val: 1,
        next: Some(Box::new(ListNode {
            val: 1,
            next: Some(Box::new(ListNode {
                val: 2,
                next: Some(Box::new(ListNode {
                    val: 3,
                    next: Some(Box::new(ListNode {
                        val : 4,
                        next: Some(Box::new(ListNode {
                            val: 4,
                            next: None,
                        })),
                    })),
                })),
            })),
        })),
    }));
    assert_eq!(merge_two_lists(l1.clone(), l2.clone()), l3.clone());
    assert_eq!(merge_two_lists2(l1.clone(), l2.clone()), l3.clone());
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值