链表题(3)

链表题

正文开始前给大家推荐个网站,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站
本篇内容继续给大家带来链表的一些练习题

链表分割

知识点:
编程基础 链表
描述:
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。

链接:

https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking

比如:输入5 3 2 1 2 7 8 9
x值:4
输出:
3 2 1 2 5 7 8 9

思路:
那么我们可以用两个链表来分别封装小于x值的链表,和大于x值的链表,之后让链表1的尾节点指向链表2的头节点即可。

class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        struct ListNode* head1,* tail1,* head2,*tail2;//定义链表1、2的头节点和循环指针
        head1=tail1=(struct ListNode*)malloc(sizeof(struct ListNode));//开辟哨兵位
        head2=tail2=(struct ListNode*)malloc(sizeof(struct ListNode));//开辟哨兵位
        struct ListNode* cur=pHead;//cur指针遍历
        while(cur)//遍历原链表
        {
            if(cur->val<x)//如果小于x值都赋给链表1
            {
                tail1->next=cur;//cur赋值给哨兵位指向的下一个节点
                tail1=tail1->next;//链表1移动
            }
            else //大于x值赋给链表2
            {
                tail2->next=cur;//cur赋值给哨兵位指向的下一个节点
                tail2=tail2->next;//链表2移动
            }
            cur=cur->next;//原链表移动 
        }
        tail1->next=head2->next;//将两个链表连起来,让链表1的尾指针指向链表2的哨兵位指向的节点
        tail2->next=NULL;//链表2尾指针指向空指针
        pHead=head1->next;//链表1哨兵位指向的节点充当新的头节点
        free(head1);//释放链表1和链表2的哨兵位
        free(head2);
        return pHead;//返回新的头节点
    }
};

思路很简单,用带有哨兵位的链表的话,代码实现起来也不是很难,不用哨兵位就有些难度,大家可以尝试一下,具体解释请看代码注释。

在这里插入图片描述

反转链表

题目描述:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:

在这里插入图片描述
示例2:
在这里插入图片描述
示例3:

在这里插入图片描述
提示:

链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

题目链接:

https://leetcode.cn/problems/reverse-linked-list/description/

我们可以用3个指针来解决这个问题,n1指向空指针,n2指向头节点,n3指向第二个节点,每次循环我们让n2的next指向n1,然后把n2赋给n1,n3赋给n2,n3向后移动,遍历这个链表就可以,下一次循环就会让第二个节点的next指向第一个节点了。当n2为空指针的时候,说明已经反转进行完毕了。
图示如下:

在这里插入图片描述

struct ListNode* reverseList(struct ListNode* head) {
    if(head==NULL)//链表为空情况直接返回空指针
        return NULL;
    struct ListNode* n1=NULL;//n1初始为空指针
    struct ListNode* n2=head;//n2初始为原链表头节点
    struct ListNode* n3=head->next;//n3初始为第二个节点
    while(n2)//循环
    {
        n2->next=n1;n2的next指向n1
        n1=n2;//n2的位置给n1
        n2=n3;//n3的位置给n2
        if(n3)//只要n3不为空指针也就是n3没有走完原链表的最后一个节点
            n3=n3->next;//n3就向后移动至空指针
    }
    return n1;//返回n1,此时的n1为新链表的头节点,也就是原链表的尾节点
}

思路已经确定了,那么代码也十分容易实现,若有不理解的看注释,相信大家一定能没明白。
在这里插入图片描述
(最后截图取自力扣网,若侵权必删除。)

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值