2021-1-11删除中间节点、合并链表

题目1

实现一种算法,删除单向链表中间的某个节点(即不是第一个或最后一个节点),假定你只能访问该节点。*

示例:

输入:单向链表a->b->c->d->e->f中的节点c
结果:不返回任何数据,但该链表变为a->b->d->e->f

  1. 结点d的值换到结点c上
  2. 该节点,指向原来的d结点的下一个:e结点
class Solution {
public:
    void deleteNode(ListNode* node) {
        ListNode* pnext = node->next;
        node->val = pnext->val;
        node->next = pnext->next;
        delete pnext;
    }
};

题2

合并两个有序链表,将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

在这里插入图片描述

迭代法:

解1

设置四个结点的指针:p1、p2、p3、p4;
p1指向链表L1头节点
p2指向链表L1第二个结点作标记,便于p1、p2结点的后移
p3初始化为空;同样作为标记节点
p4指向链表L2头节点

排序过程是逐个比较链表1(p1)和链表2(p4)的结点,若p1结点比p4小,则插入到结点p4前,否则p4后移,详细过程如下:

  1. 设置循环条件:链表p1、p4结点均不等于空,循环内部:
    a.若p1结点值>=p4结点值:p4结点后移
    b.若p1结点值<p4结点值:p1结点插入到链表L2的p4结点前一个,p1指向链表L1下一个结点(p1 = p2;p2 = p2->next)

  2. 循环结束,p1、p4至少有一个指NULL

  3. 若p1=NULL,说明链表L1已全部结点已插入到L2中,

  4. 若p4=NULL,则将L1剩余的已有序的结点拼接到L2后面即可

    L1:0 2 4 7 9
    L2:1 3 4
    

初始:
在这里插入图片描述
0<1,p1结点插入p4前,p1、p2后移;

在这里插入图片描述
2 > 1,p3、p4后移
在这里插入图片描述
2 < 3,2插入到3前面,p1、p2后移
在这里插入图片描述
4 > 3,p3、p4后移;
在这里插入图片描述
4 = 4,p3、p4后移
在这里插入图片描述
结束循环,p4为空,则将L1拼接到L2后面,排序成功。
在这里插入图片描述

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        //1. 定义指针
        if(l1 == NULL) return l2;
        if(l2 == NULL) return l1;

        ListNode* p1(NULL);
        ListNode* p2(NULL);
        ListNode* p3(NULL);
        ListNode* p4(NULL);

        p1 = l1;
        p2 = l1->next;
        p3 = NULL;
        p4 = l2;
        while(p1 != NULL && p4 != NULL)
        {
            if(p4->val <= p1->val)
            {
                p3 = p4;
                if(p4 != NULL)
                    p4 = p4->next;
            }
            else
            {
                if(p3 == NULL)
                {
                    p1->next = p4;
                    l2 = p1;
                }
                    
                else
                {
                    p3->next = p1;
                    p1->next = p4;
                }
                p3 = p1;
                p1 = p2;
                if(p2 != NULL)
                    p2 = p2->next;
            }
        }
        if(p4 == NULL)
        {
            p3->next = p1;
        }
        return l2; 
};

解2

  1. 设置1结点,并初始化(设值-1),prev、pHead指向它;
  2. 设置循环结束条件:l1、l2均不指向空,循环内部:
    a. 比较l1和l2结点大小
    b. prev->next指向较小那个结点
    c. prev指向gai节点,该节点的指针后移(l1或l2)
  3. 循环结束,哪个指针不为空,拼接到prev后面
  4. 返回pHead->next
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
       // 迭代算法
        ListNode* pHead = new ListNode(-1);
        ListNode* prev = pHead;
        while(l1 != NULL && l2 != NULL)
        {
            //l1<=l2,prev下一节点l1;prev=l1,l1后移;;
            if(l1->val <= l2->val)
            {
                prev->next = l1;
                prev = l1;
                l1 = l1->next;
            }
            else
            {
                prev->next = l2;
                prev = l2;
                l2 = l2->next;
            }
        }
        if(l1 == NULL)
            prev->next = l2;
        else
            prev->next = l1;
        return pHead->next;
    }
};

递归算法:

递归调用:
若l1<l2:mergeTwoLists(l1->next,l2)
若l1>=l2:mergeTwoLists(l1,l2->next)
结束条件:
l1为null:返回l2;
l2为null:返回l1;

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(l1 == NULL)
            return l2;
        if(l2 == NULL)
            return l1;
        if(l1->val < l2->val)
        {
            l1->next = mergeTwoLists(l1->next,l2);
            return l1;
        }
        else
        {
            l2->next = mergeTwoLists(l1,l2->next);
            return l2;
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值