单链表的应用(快慢指针)

一.移除链表元素

思路1.额外设prev,next两变量存值

先通过遍历链表找到pcur前一个节点prev,再将pcur后一个节点next存起来,再让prev->next = next,这样是一种解决方法。

思路2.创建新链表(实现)

检测pcur->val如果不等于val值,就将新节点插入原节点尾,如果是空链表则直接将头和尾节点都赋值为pcur

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) 
{
    ListNode* NewHead;
    ListNode* NewTail;    
    NewHead = NewTail = N ULL;
    ListNode* pcur = head;
    while(pcur)
    {
        if(pcur->val != val)
        {
            if(NewHead == NULL)
            {
                NewHead = NewTail = pcur;
            }
            else
            {
                NewTail->next = pcur;
                NewTail = NewTail->next;
            }
        }
        pcur = pcur->next;
    }
    if(NewHead)//如果新链表不为空
    {
        NewTail->next = NULL;
    }
    return  NewHead;//如果为空直接返回空即可
}

需要注意的是,如果给的链表就是空链表,则不进while循环,直接返回空即可。

二.反转单链表

思路1.创建新链表

创建新链表,遍历原链表,将原链表的节点拿来头插即可完成

思路2.不创建新链表,创建三个指针(实现)

改变n2的next指针,由指向n3改变至指向n1

再通过赋值操作,将n1,n2,n3向后走,究其本质其实就是改变箭头的指向,代码如下

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
    if(head == NULL)
        return head;
    ListNode* n1 = NULL;
    ListNode* n2 = head;
    ListNode* n3 = n2->next;
    while(n2)
    {
        n1 = n2->next;
        n1 = n2;
        n2 = n3;
        if(n3)
            n3 = n3->next;
    }
}

最后注意传入空链表则直接返回,n3遍历到空需要判断,让它不要再往后走了。

三.返回链表的中间节点

1.遍历原链表

定义变量count计节点数,直接返回(count / 2)->next节点,需要遍历多次。

2.快慢指针(实现)

定义两个指针fast,slow.slow一次走一步,fast一次走两步.

节点有奇数个:

fast->next == NULL时,slow节点就是中间节点

节点有偶数个:

fast == NULL时,slow节点就是中间节点 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
    ListNode* fast = head;
    ListNode* slow = head;
    while(fast && fast->next)//不能交换位置,fast为空,即证明为偶数节点,fast->next为空,即证明为奇数节点
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    //此时slow就是指向中间节点的指针
    return slow;
}

四.总结

对于链表类题,我们可以使用

创建链表

额外设值存值来避免创建链表

通过多指针来改变链表的指向

一种比较巧妙的方法-----快慢指针

......

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值