【剑指offer】17- 合并两个排序链表

题目描述
  • 输入两个递增排序的链表,合并这两个链表并且使得合并后的新链表也是按照递增排序的,链表节点定义如下:
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) 
        : val(x), next(NULL) 
    {}
};
  • 例如下图所示,给定链表1和链表2,则合并后的链表如下图所示:
    合并链表
解题思路
  • 这种题目最直接的解法,大家都可以想到,即新建一个链表,同时遍历链表1和2并且比较其节点的大小,将小的节点依次插入到新的链表中,因为链表是有序的,所以我们只需要对两条链表分别遍历一次
  • 如果要是在原链表上进行合并,首先比较两条链表的头结点,以上图为例:1 < 2,则节点1作为合并链表的头结点;此时继续拿节点 2 和节点 3 进行比较,2 < 3,则将 节点 2 链接在合并链表头节点的后面,此时我们需要记录节点 2 的下一个节点,重复上述步骤,若有一条链表已经走到尽头,则在最后将剩余链表链在合并链表的尾部,上述过程图示为:
    合并链表1
  • 思路理清楚后,我们就可以动手写代码了
代码实现
  • 实现一:递归实现。我们发现,在上述的分析过程中,我们一直重复的动作是从剩余两条链表中选择头结点,然后将其链接在合并链表的尾部,代码实现如下:
ListNode * Merge(ListNode* pHead1, ListNode* pHead2)
{
    if (pHead1 == NULL)
        return pHead2;
    if (pHead2 == NULL)
        return pHead1;
    if (pHead1->val < pHead2->val)
    {
        pHead1->next = Merge(pHead1->next, pHead2);
        return pHead1;
    }
    else
    {
        pHead2->next = Merge(pHead1, pHead2->next);
        return pHead2;
    }
}
  • 实现二:非递归
ListNode * Merge(ListNode* pHead1, ListNode* pHead2)
{
    ListNode* h1 = pHead1;
    ListNode* h2 = pHead2;
    if (pHead1 == NULL)
        return pHead2;
    if (pHead2 == NULL)
        return pHead1;

    ListNode* newHead = NULL;
    if (h1->val < h2->val)
    {
        newHead = h1;
        h1 = h1->next;
    }
    else
    {
        newHead = h2;
        h2 = h2->next;
    }
    ListNode* cur = newHead;

    while (h1 != NULL && h2 != NULL)
    {
        if (h1->val < h2->val)
        {
            cur->next = h1;
            h1 = h1->next;
            cur = cur->next;
        }
        else
        {
            cur->next = h2;
            h2 = h2->next;
            cur = cur->next;
        }
    }
    if (h1 == NULL)
        cur->next = h2;
    if (h2 == NULL)
        cur->next = h1;
    return newHead;
}

猜你喜欢

转载自blog.csdn.net/Aurora_pole/article/details/81352271