合并两个链表

本文介绍了一种合并两个有序链表的算法,通过遍历比较两个链表的元素,将较小的元素依次插入新链表中,最终实现有序链表的合并。
  1. 就是简单的合并两个链表,这里要求俩个链表是有序的。
  2. 比如[ 1 2 3 4 5] 和 [ 0 7 13] 合并之后为 [ 0 1 2 3 4 5 7 13]。
首先,简单介绍一下思路,首先区遍历俩个链表,如果第一个链表的值小于等于第二个链表的值,那么将第一个链表的值插入一个新的头节点
链表中,反之如果大于第二个链表的值,那么将第二个链表的值插入这个头节点所在的链表中,当然,这个链表一开始为空

这里就是代码,这本来是一个OJ练习题,顺便也写了一个测试

    private static Node mergeTwoList(Node list1, Node list2) {
        if (list1 == null) {
            return list2;
        }        if (list2 == null) {
            return list1;
        }       
        
         //定义了来个引用,用来遍历链表
        Node cur1 = list1;
        Node cur2 = list2;        
        Node nHead = null;
        Node nLast = null;
                
        while (cur1 != null && cur2 != null) {
            if (cur1.val <= cur2.val) {
                if (nHead == null) {
                    nHead = cur1;
                } else {
                    nLast.next = cur1;
                }
                nLast = cur1;                
                cur1 = cur1.next;
            } else {
                if (nHead == null) {
                    nHead = cur2;
                } else {
                    nLast.next = cur2;
                }
                nLast = cur2;
                cur2 = cur2.next;
            }
        }        
        if (cur1 != null) {
            nLast.next = cur1;
        } else {
            nLast.next = cur2;
        }        return nHead;
    }    

public static void main(String[] args) {
        Node n5 = new Node(5,null);
        Node n4 = new Node(4, n5);
        Node n3 = new Node(3, n4);
        Node n2 = new Node(2, n3);
        Node n1 = new Node(1, n2);//1 2 3 4 5        
        Node m3 = new Node(13,null);
        Node m2 = new Node(7, m3);
        Node m1 = new Node(0, m2);//0 7 13       
        Node result = mergeTwoList(n1, m1);
        printList(result);
    }   

 private static void printList(Node head) {
        for (Node cur = head; cur != null; cur = cur.next) {
            System.out.println(cur);
        }
    }
}
<think>好的,用户问的是如何在C++中实现合并两个有序链表的功能。我需要先整理已有的引用资料,看看里面有什么有用的信息。 根据引用[3]和[4],合并两个有序链表的基本思路是同时遍历两个链表,比较当前节点的,把较小的节点接到新链表上。为了处理方便,通常会使用一个哑节点(dummy node)作为新链表的起始,这样避免处理头节点的特殊情况。引用[5]提到需要注意当一个链表遍历完而另一个还有剩余节点的情况,这时候需要将剩余部分直接连接到新链表的末尾。 接下来,代码结构方面,引用[2]和[4]提到可以使用迭代的方法,时间复杂度是O(m+n),空间复杂度是O(1),因为只需要调整指针,不需要额外空间。引用[3]中的示例代码可能使用了哑节点,并且在循环中逐个比较节点,选择较小的插入新链表。 另外,用户可能需要注意链表的节点定义,比如在C++中,链表节点通常定义为结构体,包含和指向下一个节点的指针。例如: struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(nullptr) {} }; 然后,合并函数的实现步骤致如下: 1. 创建哑节点和当前指针指向它。 2. 循环比较两个链表的当前节点,较小的接入新链表,并移动对应链表的指针。 3. 当其中一个链表遍历完后,将另一个链表的剩余部分接上。 4. 返回哑节点的下一个节点作为合并后的头节点。 还需要考虑边界情况,比如其中一个链表为空的情况,这时候直接返回另一个链表即可。引用[5]特别提醒了这种情况的处理。 用户可能还关心如何测试代码,比如创建两个有序链表,调用合并函数,然后输出结果。引用[2]提到可以调用已定义的链表类的方法来实现,这可能涉及链表的构建和输出方法。 总结下来,回答需要分步骤解释思路,给出代码示例,并说明时间复杂度和注意事项。同时,根据用户提供的引用,确保引用正确的部分,比如哑节点的使用和剩余节点的处理。</think>### 分步实现合并两个有序链表 #### 1. 定义链表节点结构体 ```cpp struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} }; ``` #### 2. 创建哑节点简化操作 使用哑节点作为新链表的起始点,避免处理头节点特例[^3]: ```cpp ListNode* dummy = new ListNode(-1); ListNode* current = dummy; ``` #### 3. 双指针遍历比较 同时遍历两个链表,选择较小的节点接入新链表[^4]: ```cpp while (l1 && l2) { if (l1->val <= l2->val) { current->next = l1; l1 = l1->next; } else { current->next = l2; l2 = l2->next; } current = current->next; } ``` #### 4. 处理剩余节点 将未遍历完的链表直接拼接至新链表末尾[^5]: ```cpp current->next = (l1 != nullptr) ? l1 : l2; ``` #### 完整代码实现 ```cpp ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode dummy(-1); ListNode* current = &dummy; while (l1 && l2) { if (l1->val <= l2->val) { current->next = l1; l1 = l1->next; } else { current->next = l2; l2 = l2->next; } current = current->next; } current->next = l1 ? l1 : l2; return dummy.next; } ``` #### 复杂度分析 * **时间复杂度**:$O(m+n)$,需遍历两个链表所有节点 * **空间复杂度**:$O(1)$,仅使用固定数量的指针变量[^4] #### 测试用例示例 ```cpp // 创建链表1: 1->3->5 ListNode* l1 = new ListNode(1); l1->next = new ListNode(3); l1->next->next = new ListNode(5); // 创建链表2: 2->4->6 ListNode* l2 = new ListNode(2); l2->next = new ListNode(4); l2->next->next = new ListNode(6); // 合并后结果应为1->2->3->4->5->6 ListNode* merged = mergeTwoLists(l1, l2); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值