// [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());
}
leetcode简单题6 N.21 合并两个有序链表(对指针要有理解)rust描述
于 2024-06-29 18:17:34 首次发布