c++ 如何合并两个有序链表

合并两个有序链表是一个经典的算法问题。下面将详细讲解使用C++解决这个问题的完整攻略。

问题描述

合并两个有序链表为一个新的有序链表。

解决思路

迭代法

迭代法的思路是:比较两个链表的节点,将较小的节点加入合并后的链表,直到有一个链表为空。此时将另一个非空链表节点全部加入合并后的链表即可。

递归法

递归法的思路是:比较两个链表的头部,较小的节点加入合并后的链表,然后继续递归下去,更新链表头,直到有一个链表为空。此时将另一个非空链表节点全部加入合并后的链表即可。

选择使用哪种方法取决于个人喜好和算法效率。通常来说,迭代法的效率要高于递归法。

代码实现

迭代法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode dummyHead(0);
        ListNode* tail = &dummyHead;
        while (l1 && l2) {
            if (l1->val < l2->val) {
                tail->next = l1;
                l1 = l1->next;
            } else {
                tail->next = l2;
                l2 = l2->next;
            }             
            tail = tail->next;
        }
        tail->next = l1 ? l1 : l2;
        return dummyHead.next;
    }
};

递归法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (!l1) return l2;
        if (!l2) return l1;
        if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1;
        } else {
            l2->next = mergeTwoLists(l2->next, l1);
            return l2;
        }
    }
};

示例代码

#include <iostream>
#include <vector>
using namespace std;

// Definition for singly-linked list.
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode dummyHead(0);
        ListNode* tail = &dummyHead;
        while (l1 && l2) {
            if (l1->val < l2->val) {
                tail->next = l1;
                l1 = l1->next;
            } else {
                tail->next = l2;
                l2 = l2->next;
            }             
            tail = tail->next;
        }
        tail->next = l1 ? l1 : l2;
        return dummyHead.next;
    }
};

void printList(ListNode* head) {
    while (head) {
        cout << head->val << " ";
        head = head->next;
    }
    cout << endl;
}

int main() {
    Solution s;
    vector<int> nums1 = {1, 3, 5, 7};
    vector<int> nums2 = {2, 4, 6, 8};
    ListNode* l1 = new ListNode(0);
    ListNode* l2 = new ListNode(0);
    ListNode* p = l1;
    for (int num : nums1) {
        p->next = new ListNode(num);
        p = p->next;
    }
    p = l2;
    for (int num : nums2) {
        p->next = new ListNode(num);
        p = p->next;
    }
    ListNode* merged = s.mergeTwoLists(l1->next, l2->next);
    printList(merged); // 1 2 3 4 5 6 7 8
    return 0;
}
#include <iostream>
#include <vector>
using namespace std;

// Definition for singly-linked list.
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (!l1) return l2;
        if (!l2) return l1;
        if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1;
        } else {
            l2->next = mergeTwoLists(l2->next, l1);
            return l2;
        }
    }
};

void printList(ListNode* head) {
    while (head) {
        cout << head->val << " ";
        head = head->next;
    }
    cout << endl;
}

int main() {
    Solution s;
    vector<int> nums1 = {1, 3, 5, 7};
    vector<int> nums2 = {2, 4, 6, 8};
    ListNode* l1 = new ListNode(0);
    ListNode* l2 = new ListNode(0);
    ListNode* p = l1;
    for (int num : nums1) {
        p->next = new ListNode(num);
        p = p->next;
    }
    p = l2;
    for (int num : nums2) {
        p->next = new ListNode(num);
        p = p->next;
    }
    ListNode* merged = s.mergeTwoLists(l1->next, l2->next);
    printList(merged); // 1 2 3 4 5 6 7 8
    return 0;
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c++ 如何合并两个有序链表 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C++多线程编程详解

    我会详细讲解C++多线程编程的攻略。对于多线程编程,一般分为以下几个步骤: 1. 包含头文件 要进行多线程编程,需要包含头文件<thread>。 #include <thread> 2. 创建线程 使用std::thread类创建一个线程,并将需要执行的函数作为参数传入。 void my_func() { // 线程要执行的代码 } …

    C 2023年5月22日
    00
  • OpenSCA技术原理npm依赖示例解析

    OpenSCA技术原理npm依赖示例解析 OpenSCA是一种开放式的SOAP(简单对象访问协议)组件体系结构,可以用于构建SOA(面向服务的架构)应用程序。OpenSCA技术使用了许多依赖关系,其中包括npm依赖。下面是本文的攻略。 安装Node.js 在开始使用OpenSCA和npm依赖之前,需要安装Node.js。如果您没有安装,请前往Node.js官…

    C 2023年5月23日
    00
  • C语言实现简单的推箱子游戏

    C语言实现简单的推箱子游戏攻略 游戏规则 推箱子游戏是一款智力类游戏,玩家需要通过推动木箱到指定的位置来完成游戏,游戏难度逐渐增加。 游戏规则如下: 玩家可以通过键盘上的 ↑、↓、←、→ 控制人物(P)的移动,人物可以向四个方向行走; 如果人物面对着一个箱子(O),玩家按下操作键,木箱就会朝着人物所面对的方向移动一个格子; 箱子在游戏界面移动的过程中,必须始…

    C 2023年5月23日
    00
  • 浅谈Linux环境下并发编程中C语言fork()函数的使用

    浅谈Linux环境下并发编程中C语言fork()函数的使用 简介 在Linux环境下C语言的并发编程中,fork()函数是一种常见的创建新进程的方式。这个函数会创建一个子进程,子进程与父进程在某些方面是相同的,在另一些方面又是不同的。本文将详细讲解fork()函数的使用。 fork()函数的声明 fork()函数的声明如下所示: #include <u…

    C 2023年5月22日
    00
  • C++ Clock类模拟实现闹钟运行

    C++中的Clock类可以用于时钟和计时器的计算和管理。模拟实现一个闹钟可以借助Clock类的一些方法和属性,具体步骤如下: 1. 定义Clock类 首先需要定义一个Clock类,至少需要有开始计时、停止计时、获取当前时间等方法。 class Clock { public: void start(); // 开始计时 void stop(); // 停止计时…

    C 2023年5月23日
    00
  • 详解c++ atomic原子编程中的Memory Order

    当使用C++中的原子类型进行编程时,需要指定原子操作的内存顺序(Memory Order),以保证多线程下的正确性和一致性。 C++中原子操作的内存顺序一共有4种: memory_order_relaxed:最轻松的内存顺序,不会保证原子操作的顺序,也不保证操作的内存可见性。当我们要进行仅仅是读写共享内存而无需考虑同步问题的操作时,可以使用memory_or…

    C 2023年5月23日
    00
  • C++实现ping程序实例

    下面我将详细解释如何使用C++实现ping程序。先说一下ping程序的原理,它的作用是测试网络连接是否正常,通常是通过向相应的网络主机发送数据包并接收响应包,来计算数据包的往返时间和丢失率。 在C++中,要实现ping程序,我们需要使用操作系统提供的网络编程API,比如Linux中的socket API。下面是实现ping程序的具体步骤: 创建socket …

    C 2023年5月23日
    00
  • C++实现查找中位数的O(N)算法和Kmin算法

    C++实现查找中位数的O(N)算法和Kmin算法 中位数 中位数指的是一组数据中间位置的数。 对于一组无序数据而言,可以使用快速排序、堆排序等算法求出其中位数。 但是这些算法的时间复杂度较高。 在此讨论的是时间复杂度为O(N)的算法。 O(N)算法 O(N)算法的基本思想:将一组数据分成若干组,然后对于每一组进行处理。 首先随机选择一个数作为参考数,然后将数…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部