96SEO 2026-02-20 02:03 0
今天我们要实现的全部功能就如下所示功能很多我们一步一步来一起来手撕链表吧加油

}SLNode;当然了我们肯定得写一个接口来申请动态开辟的一个结点(这个我们在前面写顺序表的时候就写过了就不过多介绍这个了)可以看下图帮助自己理解
(SLNode*)malloc(sizeof(SLNode));if
代码思路单链表中我们可以知道它是如下图这种形式每一个结构体中存着下个节点的地址我们可以通过判断结构体指针是否为空指针来依次打印
在写代码之前我们需要重新复习一下对形参的修改不会改变实参,形参是实参的一个临时拷贝请牢牢记住后面有很大的作用这在后面帮助我们理解单链表有很大的帮助。
由这些可以知道我们要想修改一级指针里面的值我们要用二级指针接收。
接下来我们就开始上我们的第一盘凉菜了
代码思路首先我们肯定要考虑两种情况即一种是链表是空的什么都没有另一种即链表中有值需要我们尾增新的值我们可以借助下图来帮助我们分析我们通过循环找到该链表的尾结点然后让尾部结点中的next假如链表中没有值是空链表我们直接指向新的结点即可。
{assert(pphead);//判断传过来的链表是否存在SLNode*
NULL)//判断传来的是否是空指针如果为空就直接开辟新的节点{*pphead
代码思路单链表的头**们依然得借助图像来帮助我们分析如下图我们让*phead指向newnode开辟的结点在让newnode-next指向原本的头结点即可完成头插当然我们依然得用二级指针接收因为我们要修改的一级指针。
CreateNewNode(x);//开辟一个新的节点newnode-next
*pphead;//将头节点地址存放在next中*pphead
//在让头节点指向Newnode此时newnode就称为了头节点
思路分析在单链表的尾部删除中我们需要考虑两种情况一种为单节点一种为多节点即一种删除完后链表中的值为空另一种即删除最后一个后仍然还有结点。
当然了我们依然得先画图分析如下图。
我们看图一可以知道我们直接找到
*phead置为空指针即可完成单结点的删除。
我们看图二我们得找到一个尾结点将它释放将尾部结点的前一个结点中的next即保留最后一个结点中的地址让它置为空指针即删除完毕由此我们可以通过一个快慢指针一个指针往后走一个保留前一个结点的地址因此我们可以找到最后一个结点并保留前一个结点的地址。
{//一个节点//多个节点assert(pphead);assert(*pphead);if
NULL)//单节点{free(*pphead);//释放pphead所在的空间*pphead
NULL;//将pphead置为空指针}else//多节点{SLNode*
NULL)//找到尾节点{//倒数第一步(尾节点的前一个节点时)prev
tail-next;//此时找到了NULL}free(tail);//释放掉记录尾结点的地址prev-next
NULL;printf(打印删除之前的\n);SLTPushFront(plist,
9);SLTPrint(plist);printf(打印删除之后的\n);SLTPopback(plist);//尾删SLTPopback(plist);SLTPrint(plist);
{//Test1();//Test2();Test3();return
*phead指向原本的第二个节点即可因此我们需要用一个结构体指针指向第二个节点将其保留下来传给原本的头指针。
可以通过下图帮助自己分析如下图。
{//空assert(pphead);//多个节点SLNode*
(*pphead)-next;free(*pphead);*pphead
NULL;printf(打印删除之前的\n);SLTPushFront(plist,
9);SLTPrint(plist);printf(打印删除之后的\n);SLTPopFront(plist);//头删SLTPopFront(plist);SLTPrint(plist);
{//Test1();//Test2();//Test3();Test4();return
思路分析我们可以通过指针去一次遍历链表中的数据找到对应值即找到了返回此时指针的地址遍历到最后一个NULL也没有找到时即返回空指针如下图
NULL;printf(打印删除之前的\n);SLTPushFront(plist,
9);SLTPrint(plist);printf(查找结果:\n);printf(%p\n,SLFind(plist,
{//Test1();//Test2();//Test3();//Test4();Test5();return
思路分析如果是多节点要想实现在pos的前面插入首先我们要找到pos的前面一个节点让它指向我们新开辟的节点newnode然后再让newnode-next指向我们原本pos的所在的节点就完成了头插如下图1所示。
如果是单节点的时候就是相当于头**们只需要判断是否是单节点如果是就直接调用头插函数即可。
{assert(pphead);assert(pos);assert(*pphead);//单节点if
NULL;printf(原本的值\n);SLTPushFront(plist,
9);SLTPrint(plist);printf(插入之后的结果\n);SLNode*
{//Test1();//Test2();//Test3();//Test4();//Test5();Test6();return
思路分析当然了单链表的删除我们依然得采用俩种情况一种情况为单节点一种情况为多节点我们先来分析多节点如果是多节点的情况我们应当找到pos的节点将它释放掉并且我们应当将pos的前一个节点将他记录下来并让它指向pos之后的一个节点此时我们即可完成数值的删除。
如下图所示如果是单节点的情况我们可以直接当成头删直接调用头删函数即可。
{assert(pphead);//判断传来的结构体是否存在assert(*pphead);//判断是否为空指针assert(pos);//判断空地址if
pos){SLTPopFront(pphead);//头删}else{SLNode*
NULL;printf(原本的值\n);SLTPushFront(plist,
9);SLTPrint(plist);printf(删除之后的结果\n);SLNode*
{//Test1();//Test2();//Test3();//Test4();//Test5();//Test6();Test7();return
思路分析要想销毁单链表中的所有值我们只需要把单链表中的每个节点给它释放并最后让头节点指向空指针即可因此我们需要借助两个指针一个指针指向tail的下一个节点当释放掉tail后让tail可以指向下一个节点再依次释放这样就可以达到链表的销毁的作用如下图所示。
{assert(*pphead);//判断传来的是否已经是空指针SLNode*
tail-next;free(tail);//依次释放tail
NULL;printf(原本的值\n);SLTPushFront(plist,
9);SLTPrint(plist);printf(删除之后的结果\n);SLTDestroy(plist);SLTPrint(plist);
{//Test1();//Test2();//Test3();//Test4();//Test5();//Test6();Test8();return
结语今天的内容就到这里吧谢谢各位的观看如果有讲的不好的地方也请各位多多指出作者每一条评论都会读的谢谢各位。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback