设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间20 现在时间20 缓存数据 和聪明人交流,和靠谱的人恋爱,和进取的人共事,和幽默的人随行。晚安!

和聪明人交流,和靠谱的人恋爱,和进取的人共事,和幽默的人随行。晚安!

查看: 2497|回复: 3

C语言实现无头单向链表的示例代码

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:231
  • 打卡月天数:1
  • 打卡总奖励:3589
  • 最近打卡:2025-12-11 20:52:00
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
432
主题
397
精华
0
金钱
4870
积分
896
注册时间
2023-1-6
最后登录
2025-12-11

发表于 2023-2-13 16:09:04 | 显示全部楼层 |阅读模式
一、易错的接口实现



1.1 新节点开辟函数


由于创建一个新节点是频繁的操作,所以封装为一个接口最佳。
链表节点的属性有:(1)数值。(2)指向下一个节点的地址。(3)自身地址。
  1. static SLTNode* BuySListNode(SLTDataType x)
  2. {
  3. SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
  4. //开辟失败
  5. if (newnode == NULL)
  6. {
  7.   printf("malloc fail\n");
  8.   exit(-1);
  9. }
  10. //初始化
  11. newnode->data = x;
  12. newnode->next = NULL;
  13. return newnode;
  14. }
复制代码
数值和next地址都由此函数初始化,自身地址则由函数的返回值返回。
要注意使用malloc函数时,可能存在开辟空间失败的情况,这时会返回NULL。

1.2 尾插


尾插的难点在于存在特殊情况。
当对非空链表和空链表进行尾插时,所需代码不同。
对非空链表尾插时,算法是:找到此链表的尾部,即遍历此链表,直至自定义的结构体指针tail的下一个节点为NULL,结束遍历。在tail的后面插入一个新节点。
对空链表尾插时,算法是:直接把新节点作为链表的头节点。
  1. void SListPushBack(SLTNode** pphead, SLTDataType x)
  2. {
  3. assert(pphead);
  4. //找尾
  5. SLTNode* tail = *pphead;
  6. if (tail == NULL)
  7. {
  8.   tail = BuySListNode(x);
  9.   *pphead = tail;
  10. }
  11. else
  12. {
  13.   while (tail->next != NULL)
  14.   {
  15.    tail = tail->next;
  16.   }
  17.   SLTNode* newnode = BuySListNode(x);
  18.   tail->next = newnode;
  19. }
  20. }
复制代码
1.3 尾删


此接口也有特殊情况处理。
当链表有一个以上的节点时,算法:遍历链表到尾部,free掉tail所在内存,改变tail之前一个节点的next,为NULL。
需要一个结构体指针变量prev来记录tail的前一个节点。
当链表只有一个节点时,算法:tail一开始就在尾部,直接free掉tail,再把prev指针(初值为NULL)赋值给头节点*pphead。
如果不单独考虑这种情况的话,会因为NULL->next而出现内存错误。
当链表没有节点时,是不可以调用尾删的,直接用assert函数报错。
  1. void SListPopBack(SLTNode** pphead)
  2. {
  3. assert(pphead);
  4. assert(*pphead);//没有节点断言报错
  5. SLTNode* prev = NULL;
  6. SLTNode* tail = *pphead;
  7. while (tail->next != NULL)
  8. {
  9.   prev = tail;
  10.   tail = tail->next;
  11. }
  12. free(tail);
  13. tail = NULL;
  14. if (prev != NULL)
  15.   prev->next = NULL;
  16. else
  17.   *pphead = prev;
  18. }
复制代码
二、常见简单接口



2.1 打印链表

  1. void SListPrint(SLTNode* phead)
  2. {
  3. SLTNode* cur = phead;
  4. while (cur)
  5. {
  6.   printf("%d->", cur->data);
  7.   cur = cur->next;
  8. }
  9. printf("NULL\n");
  10. }
复制代码
2.2 节点计数器

  1. int SListSize(SLTNode* phead)
  2. {
  3. //计数器
  4. int count = 0;
  5. SLTNode* cur = phead;
  6. while (cur)
  7. {
  8.   count++;
  9.   cur = cur->next;
  10. }
  11. return count;
  12. }
复制代码
2.3 判断是否为空链表

  1. bool SListEmpty(SLTNode* phead)
  2. {
  3. return phead == NULL;
  4. }
复制代码
2.4 通过值查找节点

  1. SLTNode* SListFind(SLTNode* phead, SLTDataType data)
  2. {
  3. //通过数据查找节点-遍历节点,判断值是否相等
  4. SLTNode* cur = phead;
  5. while (cur)
  6. {
  7.   if (cur->data == data)
  8.    return cur;
  9.   cur = cur->next;
  10. }
  11. return NULL;
  12. }
复制代码
2.5 头插

  1. void SListPushFront(SLTNode** pphead, SLTDataType x)
  2. {
  3. assert(pphead);
  4. SLTNode* newnode = BuySListNode(x);
  5. newnode->next = *pphead;
  6. *pphead = newnode;
  7. }
复制代码
2.6 头删

  1. void SListPopFront(SLTNode** pphead)
  2. {
  3. assert(pphead);
  4. assert(*pphead);
  5. SLTNode* next = (*pphead)->next;
  6. free(*pphead);
  7. *pphead = NULL;
  8. *pphead = next;
  9. }
复制代码
2.7 在任意节点后插入节点

  1. void SListInsert(SLTNode* pos, SLTDataType x)
  2. {
  3. assert(pos);
  4. SLTNode* newnode = BuySListNode(x);
  5. SLTNode* next = pos->next;
  6. pos->next = newnode;
  7. newnode->next = next;
  8. }
复制代码
2.8 在任意节点后删除节点

  1. void SListErase(SLTNode* pos)
  2. {
  3. assert(pos);
  4. assert(pos->next);
  5. SLTNode* next = pos->next;
  6. pos->next = next->next;
  7. free(next);
  8. next = NULL;
  9. }
复制代码
2.9 销毁链表

  1. void SListDestroy(SLTNode** pphead)
  2. {
  3. assert(pphead);
  4. SLTNode* cur, * nextnode;
  5. cur = *pphead;
  6. nextnode = NULL;
  7. while (cur)
  8. {
  9.   nextnode = cur->next;
  10.   free(cur);
  11.   cur = nextnode;
  12. }
  13. *pphead = NULL;
  14. }
复制代码
三、头文件相关内容



3.1 引用的库函数

  1. #include<stdio.h>
  2. #include<assert.h>
  3. #include<stdlib.h>
  4. #include<stdbool.h>
复制代码
3.2 结构体声明

  1. typedef int SLTDataType;//重定义可便于修改值的数据类型
  2. 1
  3. typedef struct SListNode
  4. {
  5. SLTDataType data;
  6. struct SListNode* next;
  7. }SLTNode;//重定义可减少代码冗余
复制代码
到此这篇关于C语言实现无头单向链表的示例代码的文章就介绍到这了,更多相关C语言无头单向链表内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
13
积分
6
注册时间
2024-12-17
最后登录
2024-12-17

发表于 2025-1-21 09:07:28 | 显示全部楼层
顶顶更健康!!!
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
20
积分
20
注册时间
2022-12-26
最后登录
2022-12-26

发表于 2025-8-20 23:45:18 | 显示全部楼层
路过,支持一下
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 打卡月天数:0
  • 打卡总奖励:63
  • 最近打卡:2025-01-20 21:43:59
等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
79
积分
12
注册时间
2023-11-27
最后登录
2025-1-20

发表于 2025-9-25 13:25:06 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼
4楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表