【LeetCode】21. Merge Two Sorted Lists - Java实现

1. 题目描述:

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

Example:

Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4

2. 思路分析:

题目的意思是合并2个有序的链表。

思路是用2个指针分别指向2个链表,比较2个节点,将较小的节点放入结果链表中并且指针后移。

3. Java代码:

源代码见我GiHub主页

代码:

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    if (l1 == null) {
        return l2;
    }
    if (l2 == null) {
        return l1;
    }

    ListNode result = new ListNode(0);
    ListNode cur = result;
    while (l1 != null && l2 != null) {
        if (l1.val < l2.val) {
            cur.next = l1;
            l1 = l1.next;
        } else {
            cur.next = l2;
            l2 = l2.next;
        }
        cur = cur.next;
    }
    if (l1 != null) {
        cur.next = l1;
    }
    if (l2 != null) {
        cur.next = l2;
    }

    return result.next;
}   
<think>嗯,用户问的是关于C语言中结构体初始化的问题。具体来说,他们看到一段代码里用到了结构体的初始化方式,比如struct ListNode dummy = { .val = 0, .next = NULL };,然后想知道是否可以写成dummy.val和dummy.next来访问这些成员。 首先,我需要确认用户的理解是否正确。结构体的成员访问在C语言中确实是通过点操作符进行的。所以,dummy.val和dummy.next这样的写法是正确的,没有问题。用户可能对结构体初始化语法和成员访问有些混淆,需要明确这两者的区别。 接下来,用户提供的代码示例中使用了C99的指定初始化器(designated initializers),也就是在初始化结构体时指定成员的名称,比如.val = 0。这种写法在C99及以后的版本中是合法的,可以明确地为特定成员赋值,而不用按照结构体定义的顺序。这有助于代码的可读性,尤其是当结构体有很多成员时。 然后,用户提到的代码中创建了一个哨兵节点(dummy node),用来简化链表操作。这里cur指针指向dummy,之后通过cur->next来链接新的节点,这样就不需要处理头节点的特殊情况。这部分逻辑是正确的,但用户可能更关心结构体成员的访问方式是否正确。 需要进一步解释的是,结构体变量在定义时初始化和使用时的成员访问是不同的阶段。初始化时的指定初始化器语法只是在创建结构体实例的时候使用,而后续访问成员则是通过点操作符或者箭头操作符(对于指针)进行的。例如,dummy.val和dummy.next是正确的访问方式,而如果有一个结构体指针ptr,则需要用ptr->val和ptr->next。 可能用户看到代码中使用了.来初始化,担心是否在访问时也必须使用同样的方式。需要明确的是,初始化语法中的.val是初始化时的指定,而后续访问成员是另一回事,两者语法上都是点操作符,但上下文不同。 另外,用户可能对结构体的内存分配和初始化过程不太清楚。在C语言中,局部变量的结构体(如dummy)会在栈上分配内存,初始化时指定的成员会被赋予相应的值,未指定的成员会被初始化为0或NULL(根据编译器实现)。因此,dummy.next在这里被显式初始化为NULL,其他成员如果存在的话会被默认初始化为0。 总结一下,用户的问题核心在于确认结构体成员访问的正确性,以及初始化语法的理解。需要明确回答他们:是的,可以写成dummy.val和dummy.next来访问这些成员,这符合C语言的语法规则。同时,解释初始化语法和成员访问的区别,确保用户明白这两者是不同的操作阶段。</think>在 C 语言中,`.val` 和 `.next` 的写法是完全正确的,这是结构体成员的访问语法。您提到的两种写法本质上是等价的,区别在于初始化语法: ▋ 代码解析 ▋ 1. **C99 标准写法**(指定初始化器) ```c struct ListNode dummy = { .val = 0, // 显式初始化 val 成员 .next = NULL // 显式初始化 next 成员 }; ``` 这是 C99 引入的「指定初始化器」(Designated Initializers),优点: - 初始化顺序可与结构体定义顺序不同 - 未指定的成员会自动初始化为 0/NULL - 可读性更强(尤其在多成员结构体中) 2. **传统写法** ```c struct ListNode dummy = {0, NULL}; ``` 需要严格按照结构体成员的声明顺序初始化 ▋ 访问成员的正确方式 ▋ 无论采用哪种初始化方式,访问成员时都使用 `.` 操作符: ```c printf("%d", dummy.val); // ✅ 正确 struct ListNode* p = dummy.next; // ✅ 正确 ``` ▋ 哨兵节点的作用 ▋ 原代码中 `dummy` 节点的精妙之处: 1. **简化边界处理**:无需单独处理头节点为空的情况 2. **统一操作逻辑**:所有节点(包括第一个节点)都通过 `cur->next` 插入 3. **内存安全**:`dummy` 是栈变量,生命周期随函数自动释放 ▋ 完整示例 ▋ ```c struct ListNode { int val; struct ListNode* next; }; int main() { // 初始化方式一:C99 指定初始化器(推荐) struct ListNode dummy1 = { .val = 0, .next = NULL }; // 初始化方式二:传统顺序初始化 struct ListNode dummy2 = { 0, NULL }; // 成员访问演示 dummy1.val = 10; // ✅ 修改 val dummy1.next = &dummy2; // ✅ 修改 next return 0; } ``` 建议优先使用 C99 的指定初始化器,可显著提升代码可读性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值