【数据结构】【C语言】-----链表OJ(上)

大家好,我是Abert。上篇文章给大家讲解了单链表的结构及实现过程,这篇文章我们联系一些单链表的题目。


文章目录

一、反转链表

二、链表的中间节点

三、链表中倒数第k个结点

四、合并两个有序链表

五、移除链表元素


正文

一、反转链表

这道题的要求是把链表反转。

有两种情况需要考虑:

1. 链表为空链表

2. 链表非空

当链表为空时,直接返回空。

不为空时:

 下面时代码实现过程:(OJ接口型)

struct ListNode* reverseList(struct ListNode* head)
{
    if (head == NULL)
    {
        return NULL;
    }
    struct ListNode* cur = head;
    struct ListNode* newhead = NULL;
    while (cur)
    {
        struct ListNode* next = cur->next;

        //头插
        cur->next = newhead;
        newhead = cur;

        cur = next;
    }

    return newhead;


}

二、链表的中间节点

这道题是找到链表的中间节点并返回

当链表为奇数个时,返回中间元素。如:1 2 3 4 5  返回 3

当链表为偶数个时,返回中间两个元素的第二个,如:1 2 3 4 5 6 7 8  返回 5 

先考虑链表为空的情况,为空返回NULL

不为空找中间节点并返回

 下面时代码实现过程:

struct ListNode* middleNode(struct ListNode* head)
{
    if (head == NULL)
    {
        return NULL;
    }

    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

三、链表中倒数第k个结点

 这道题找寻倒数第k个节点并返回

首先考虑当链表为空时,返回NULL

当链表不为空时:

 下面是代码实现过程:

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) 
{
    if (pListHead == NULL)
    {
        return NULL;
    }
    
    struct ListNode* fast = pListHead;
    struct ListNode* slow = pListHead;
    
    while(k--)
    {
        if (fast == NULL)
        {
            return NULL;
        }
        fast = fast->next;
    }
    
    while(fast)
    {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;
}

四、合并两个有序链表

 这道题是将两个升序链合并为一个升序链表

其中一个链表为空,返回不为空的链表的头节点

两个均为空则返回NULL

具体过程:

上面操作完毕之后,两个链表可能依然都不为空,也有可能都为空,也有可能一个空一个非空。

我们需要执行下面的操作完善:

 

具体过程图不好展示,大家根据思路可以自行绘画过程。

下面是代码实现过程:

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
    if (list1 == NULL)
    {
        return list2;
    }
    if (list2 ==    NULL)
    {
        return list1;
    }

    struct ListNode* head, *tail;
    head = tail = NULL;

    while (list1 && list2)
    {
        if (list1->val < list2->val)
        {
            if (tail == NULL)
            {
                tail = head = list1;
            }
            else
            {
                tail->next = list1;
                tail = tail->next;
            }
            list1 = list1->next;
        }
        else
        {
            if (tail == NULL)
            {
                tail = head = list2;
            }
            else
            {
                tail->next = list2;
                tail = tail->next;
            }
            list2 = list2->next;
        }
    }
    if (list1)
    {
        tail->next = list1;
    }
    if (list2)
    {
        tail->next = list2;
    }
    return head;
}

 


五、移除链表元素

这道题要将链表中指定元素删除 

需要考虑以下情况:

要删除的元素恰好是头节点(头删)

链表中的元素全是需要删除的元素(返回head   (head 为 NULL))

下面时具体过程:

整体过程比较简单,和上题类似。

下面时代码实现过程:

struct ListNode* removeElements(struct ListNode* head, int val)
{
    struct ListNode* prev = NULL;
    struct ListNode* cur = head;

    while (cur)
    {
        if (cur->val == val)
        {
            //头删
            if (cur == head)
            {
                cur = head->next;
                free(head);
                head = cur;
            }
            else
            {
                //删除
                prev->next = cur->next;
                free(cur);
                cur = prev->next;
            }
        }
        else
        {
           prev = cur;
           cur = cur->next;
        }
    }
    return head;
}

 


做完这些题之后,相信大家对单链表的理解会上升一个层次。

以上就是这篇文章的全部内容,欢迎大家学习交流。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值