• 单链表经典算法题 1


    前言 

    学习了单链表,我们就做一些题来巩固一下。还有就是解题方法不唯一,我就只讲述为自己的方法。

    目录

    前言 

    1.移除链表元素

     思路

    代码 

    2.反转链表

     思路

     代码 

    3.链表的中间节点

    思路 

     代码 

    总结


    1.移除链表元素

     思路

    我们创建一个新的表,来储存和val值不一样的节点。还可以在原表上删除和val值相同的节点。

    这里我是新创建一个表来接受不等于val的节点。通过发现我们应该通过采取尾插的方式来储存新节点。如果循环里面就只要尾插会导致新表的头节点还是指向空指针,导致输出错误。所以还要考虑新链表的头节点是否为空,为空的话我们就新表的头节点和尾节点指向第一个节点。

    完成以上步骤后会变成下面的样子,最后一个节点还是指向要被删除的节点。导致输出结果还是含有被删除的值。所以我们要进行优化,把新链表的尾节点指向NULL。最后返回头节点就可以了。

    代码 

    1. typedef struct ListNode ListNode;
    2. struct ListNode* removeElements(struct ListNode* head, int val)
    3. {
    4. ListNode*newhead,*newtail;//新链表的头尾节点
    5. newhead=newtail=NULL;
    6. //遍历原链表
    7. ListNode* prev=head;
    8. while(prev)
    9. {
    10. if(prev->val!=val)
    11. {
    12. if(newhead==NULL)
    13. {
    14. newhead=newtail=prev;
    15. }
    16. else
    17. {
    18. newtail->next=prev;
    19. newtail=newtail->next;
    20. }
    21. }
    22. prev=prev->next;
    23. }
    24. if(newtail)
    25. newtail->next=NULL;
    26. return newhead;
    27. }

    2.反转链表

     思路

    这里我的想法是反转链表指向来实现题目的效果,定义3个节点,分别用来存储NULL、第一个节点、第二个节点循环反转指向,然后在循环让3个节点都向后移动,其中n3、最先指向空其次是n2、最后是n1  n2->next=n1;      n1=n2;     n2=n3;    n3=n3->next;   这些就是向后移动的代码

    我们最后要返回含val=5的节点所以我们就让n2充当循环结束的条件,但是这样写会出错,因为n3最早变成空指针,就可以对空指针进行解引用操作了。所以在前面加上一个if版判语句

    if(n3)n3=n3->next;   最后返回n1就可以了。

    如下图所示

     代码 

    1. typedef struct ListNode ListNode;
    2. struct ListNode* reverseList(struct ListNode* head)
    3. {
    4. if(head==NULL)
    5. {
    6. return head;
    7. }
    8. ListNode* n1,* n2,* n3;
    9. n1=NULL,n2=head,n3=n2->next;
    10. while(n2)
    11. {
    12. n2->next=n1;
    13. n1=n2;
    14. n2=n3;
    15. if(n3)
    16. n3=n3->next;
    17. }
    18. return n1;
    19. }

    3.链表的中间节点

    思路 

    这里介绍一种新奇的方法,那就是快慢指针。快指针移动两次,慢指针移动一次。这里大家先知道怎么移动行了,不用深究为什么。后面我会为大家解答的。

    根据例1移动我们发现当fast移动到最后时,slow就是我们要返回的值。我们又要把fast当作循环结束的条件。所以我们就可以想到fast->next 指针为空指针时结束循环。

    根据例2移动我们可以等到循环结束的条件为fast为空指针时为循环结束条件。

    我们把他们结合起来当作循环条件这样就万无一失了。返回慢指针(slow)

     

     代码 

    1. typedef struct ListNode ListNode;
    2. struct ListNode* middleNode(struct ListNode* head)
    3. {
    4. ListNode* slow=head;
    5. ListNode* fast=head;
    6. while(fast && fast->next)
    7. {
    8. slow=slow->next;
    9. fast=fast->next->next;
    10. }
    11. return slow;
    12. }

    总结

    做这种链表的问题最好就是画图理清思路,然后再写代码。后还会为大家讲解单链表经典算法题 2。会持续更新的哦!!!

  • 相关阅读:
    C# winform用Installer-Project打包exe程序
    【Rust日报】2022-09-19 测量 CPU 不同核心之间的延迟
    区域气象-大气化学在线耦合模式(WRF/Chem)
    SQL分层查询
    antd table 复选框禁选功能
    【缓存】OS层面缓存设计机制
    Excel 的单元格内容和单元格格式
    vscode 自定义(修改已有)主题教程
    nginx部署问题集合
    基于柯西变异的蚁狮优化算法 - 附代码
  • 原文地址:https://blog.csdn.net/2302_80867815/article/details/139638629