【数据结构】单链表练习

1.链表的中间节点

https://leetcode.cn/problems/middle-of-the-linked-list/description/

用快慢指针来解决

复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* middleNode(struct ListNode* head) 
{
    struct ListNode*fast,*slow;
    fast=slow=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}

2.反转链表

https://leetcode.cn/problems/reverse-linked-list/description/
三个指针 来解决

复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) 
{
    struct ListNode*n1,*n2,*n3;

    if(head==NULL)
    return NULL;

    n1=NULL;
    n2=head;
    n3=n2->next;
    while(n2)
    {
        //翻转
        n2->next=n1;

        //移动
        n1=n2;
        n2=n3;
        if(n3)
        n3=n3->next;
    }
    return n1;
}

3.将两个有序链表合并为一个新的有序链表并返回

21. 合并两个有序链表 - 力扣(LeetCode)

哨兵位解决

复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    struct ListNode* cur1 = list1, * cur2 = list2;
    struct ListNode* guard = NULL, * tail = NULL;

    guard = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
    tail->next = NULL;
    while (cur1 && cur2)
    {
        if (cur1->val < cur2->val)
        {
            tail->next = cur1;
            tail = tail->next;
            cur1 = cur1->next;
        }
        else
        {
            tail->next = cur2;
            tail = tail->next;
            cur2 = cur2->next;
        }
    }

    if (cur1)
    {
        tail->next = cur1;
    }
    if (cur2)
    {
        tail->next = cur2;
    }

    struct ListNode* head = guard->next;
    free(guard);
    return head;
}

4.链表分割

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

链表分割_牛客题霸_牛客网

哨兵位解决

复制代码
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {

        struct ListNode*greaterGuard,*greaterTail,*lessGuard,*lessTail;
        greaterGuard=greaterTail=(struct ListNode*)malloc(sizeof(struct ListNode));
        lessGuard=lessTail=(struct ListNode*)malloc(sizeof(struct ListNode));
        greaterGuard->next=lessGuard->next=NULL;

        struct ListNode*cur=pHead;
        while(cur)
        {
            if(cur->val<x)
            {
                lessTail->next=cur;
                lessTail=lessTail->next;
            }
            else
            {
                greaterTail->next=cur;
                greaterTail=greaterTail->next;
            }
            cur=cur->next;
        }
        lessTail->next=greaterGuard->next;
        greaterTail->next=NULL;

        pHead=lessGuard->next;
        free(lessGuard);
        free(greaterGuard);
        return pHead;
    }
};

5.相交链表

160. 相交链表 - 力扣(LeetCode)

复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
    struct ListNode* tailA = headA, * tailB = headB;
    int lenA = 1, lenB = 1;

    // 处理空链表的情况
    if (headA == NULL || headB == NULL) {
        return NULL;
    }

    while (tailA->next)
    {
        tailA = tailA->next;
        lenA++;
    }
    while (tailB->next)
    {
        tailB = tailB->next;
        lenB++;
    }

    // 如果尾节点不同,则链表不相交
    if (tailA != tailB)
        return NULL;

    int gap = abs(lenA - lenB);

    struct ListNode* longlist = headA, * shortlist = headB;

    // 确定长链表和短链表
    if (lenA > lenB)
    {
        longlist = headA;
        shortlist = headB;
    }
    else
    {
        longlist = headB;
        shortlist = headA;
    }

    // 长链表先走gap步
    while (gap--)
    {
        longlist = longlist->next;
    }

    // 同步遍历找相交节点
    while (longlist != shortlist)
    {
        longlist = longlist->next;
        shortlist = shortlist->next;
    }

    return longlist;
}
相关推荐
程序员黑豆20 小时前
Java 注释详解:单行、多行与文档注释的完整指南
java·前端·ai编程
剪刀石头布啊20 小时前
antd中可编辑表格中巧用useWatch实现联动高性能效果,以及定制延伸学习
前端
油丶酸萝卜别吃21 小时前
前端转全栈学习路线
前端·学习
浮生望21 小时前
前端路由进阶:History API原理与手写HistoryRouter
前端
Doraemomo21 小时前
数据结构-环形链表
java·数据结构·链表
数智工坊21 小时前
Zotero自建Ubuntu WebDAV附件同步方案(完美解决存储空间不足)
linux·运维·ubuntu
陆枫Larry21 小时前
JavaScript 中的竞态是什么,为啥会有竟态?
前端
ltl1 天前
HTTP/3 实战:从 QUIC 到 H3 的完整请求链路
linux
ltl1 天前
POSIX 文件锁:flock、fcntl 与 NFS 上的工程陷阱
linux
ltl1 天前
CUDA 生态:cuBLAS、cuDNN、NCCL、Triton、CUTLASS
linux