单链表经典算法题 1

前言

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

目录

前言

1.移除链表元素

思路

代码

2.反转链表

思路

代码

3.链表的中间节点

思路

代码

总结


1.移除链表元素

思路

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

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

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

代码

cpp 复制代码
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) 
{
   ListNode*newhead,*newtail;//新链表的头尾节点
   newhead=newtail=NULL;
   //遍历原链表
   ListNode* prev=head;
   while(prev)
   {
    if(prev->val!=val)
    {
        if(newhead==NULL)
        {
            newhead=newtail=prev;
        }
        else
        {
            newtail->next=prev;
            newtail=newtail->next;
        }
    }
    prev=prev->next;
   }
   if(newtail)
   newtail->next=NULL;
   return newhead;
}

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就可以了。

如下图所示

代码

cpp 复制代码
typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) 
{
    if(head==NULL)
    {
        return head;
    }
    ListNode* n1,* n2,* n3;
    n1=NULL,n2=head,n3=n2->next;
    while(n2)
    {
        n2->next=n1;
        n1=n2;
        n2=n3;
        if(n3)
        n3=n3->next;
    }
    return n1;
}

3.链表的中间节点

思路

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

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

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

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

代码

cpp 复制代码
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) 
{
    ListNode* slow=head;
    ListNode* fast=head;
    while(fast && fast->next)
    {
         slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}

总结

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

相关推荐
BUG收容所所长3 分钟前
二分查找的「左右为难」:如何优雅地找到数组中元素的首尾位置
前端·javascript·算法
itsuifengerxing41 分钟前
python 自定义无符号右移
算法
猎板PCB厚铜专家大族1 小时前
高频 PCB 技术发展趋势与应用解析
人工智能·算法·设计规范
dying_man1 小时前
LeetCode--24.两两交换链表中的结点
算法·leetcode
yours_Gabriel1 小时前
【力扣】2434.使用机器人打印字典序最小的字符串
算法·leetcode·贪心算法
草莓熊Lotso2 小时前
【数据结构初阶】--算法复杂度的深度解析
c语言·开发语言·数据结构·经验分享·笔记·其他·算法
KyollBM2 小时前
【CF】Day75——CF (Div. 2) B (数学 + 贪心) + CF 882 (Div. 2) C (01Trie | 区间最大异或和)
c语言·c++·算法
CV点灯大师2 小时前
C++算法训练营 Day10 栈与队列(1)
c++·redis·算法
GGBondlctrl3 小时前
【leetcode】递归,回溯思想 + 巧妙解法-解决“N皇后”,以及“解数独”题目
算法·leetcode·n皇后·有效的数独·解数独·映射思想·数学思想
武子康3 小时前
大数据-276 Spark MLib - 基础介绍 机器学习算法 Bagging和Boosting区别 GBDT梯度提升树
大数据·人工智能·算法·机器学习·语言模型·spark-ml·boosting