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

 更新时间:2021年09月26日 10:06:58   作者:燕麦冲冲冲  
本文主要介绍了C语言实现无头单向链表的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一、易错的接口实现

1.1 新节点开辟函数

由于创建一个新节点是频繁的操作,所以封装为一个接口最佳。

链表节点的属性有:(1)数值。(2)指向下一个节点的地址。(3)自身地址。

static SLTNode* BuySListNode(SLTDataType x)
{
 SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
 //开辟失败
 if (newnode == NULL)
 {
  printf("malloc fail\n");
  exit(-1);
 }
 //初始化
 newnode->data = x;
 newnode->next = NULL;
 return newnode;
}

数值和next地址都由此函数初始化,自身地址则由函数的返回值返回。

要注意使用malloc函数时,可能存在开辟空间失败的情况,这时会返回NULL。

1.2 尾插

尾插的难点在于存在特殊情况。

当对非空链表和空链表进行尾插时,所需代码不同。

对非空链表尾插时,算法是:找到此链表的尾部,即遍历此链表,直至自定义的结构体指针tail的下一个节点为NULL,结束遍历。在tail的后面插入一个新节点。

对空链表尾插时,算法是:直接把新节点作为链表的头节点。

void SListPushBack(SLTNode** pphead, SLTDataType x)
{
 assert(pphead);
 //找尾
 SLTNode* tail = *pphead;
 if (tail == NULL)
 {
  tail = BuySListNode(x);
  *pphead = tail;
 }
 else
 {
  while (tail->next != NULL)
  {
   tail = tail->next;
  }
  SLTNode* newnode = BuySListNode(x);
  tail->next = newnode;
 }
}

1.3 尾删

此接口也有特殊情况处理。

当链表有一个以上的节点时,算法:遍历链表到尾部,free掉tail所在内存,改变tail之前一个节点的next,为NULL。

需要一个结构体指针变量prev来记录tail的前一个节点。

当链表只有一个节点时,算法:tail一开始就在尾部,直接free掉tail,再把prev指针(初值为NULL)赋值给头节点*pphead。

如果不单独考虑这种情况的话,会因为NULL->next而出现内存错误。

当链表没有节点时,是不可以调用尾删的,直接用assert函数报错。

void SListPopBack(SLTNode** pphead)
{
 assert(pphead);
 assert(*pphead);//没有节点断言报错
 SLTNode* prev = NULL;
 SLTNode* tail = *pphead;
 while (tail->next != NULL)
 {
  prev = tail;
  tail = tail->next;
 }
 free(tail);
 tail = NULL;
 if (prev != NULL)
  prev->next = NULL;
 else
  *pphead = prev;
}

二、常见简单接口

2.1 打印链表

void SListPrint(SLTNode* phead)
{
 SLTNode* cur = phead;
 while (cur)
 {
  printf("%d->", cur->data);
  cur = cur->next;
 }
 printf("NULL\n");
}

2.2 节点计数器

int SListSize(SLTNode* phead)
{
 //计数器
 int count = 0;
 SLTNode* cur = phead;
 while (cur)
 {
  count++;
  cur = cur->next;
 }
 return count;
}

2.3 判断是否为空链表

bool SListEmpty(SLTNode* phead)
{
 return phead == NULL;
}

2.4 通过值查找节点

SLTNode* SListFind(SLTNode* phead, SLTDataType data)
{
 //通过数据查找节点-遍历节点,判断值是否相等
 SLTNode* cur = phead;
 while (cur)
 {
  if (cur->data == data)
   return cur;
  cur = cur->next;
 }
 return NULL;
}

2.5 头插

void SListPushFront(SLTNode** pphead, SLTDataType x)
{
 assert(pphead);
 SLTNode* newnode = BuySListNode(x);
 newnode->next = *pphead;
 *pphead = newnode;
}

2.6 头删

void SListPopFront(SLTNode** pphead)
{
 assert(pphead);
 assert(*pphead);
 SLTNode* next = (*pphead)->next;
 free(*pphead);
 *pphead = NULL;
 *pphead = next;
}

2.7 在任意节点后插入节点

void SListInsert(SLTNode* pos, SLTDataType x)
{
 assert(pos);
 SLTNode* newnode = BuySListNode(x);
 SLTNode* next = pos->next;
 pos->next = newnode;
 newnode->next = next;
}

2.8 在任意节点后删除节点

void SListErase(SLTNode* pos)
{
 assert(pos);
 assert(pos->next);
 SLTNode* next = pos->next;
 pos->next = next->next;
 free(next);
 next = NULL;
}

2.9 销毁链表

void SListDestroy(SLTNode** pphead)
{
 assert(pphead);
 SLTNode* cur, * nextnode;
 cur = *pphead;
 nextnode = NULL;
 while (cur)
 {
  nextnode = cur->next;
  free(cur);
  cur = nextnode;
 }
 *pphead = NULL;
}

三、头文件相关内容

3.1 引用的库函数

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>

3.2 结构体声明

typedef int SLTDataType;//重定义可便于修改值的数据类型
1
typedef struct SListNode
{
 SLTDataType data;
 struct SListNode* next;
}SLTNode;//重定义可减少代码冗余

到此这篇关于C语言实现无头单向链表的示例代码的文章就介绍到这了,更多相关C语言无头单向链表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • C语言实现绘制可爱的橘子钟表

    C语言实现绘制可爱的橘子钟表

    这篇文章主要为大家详细介绍了如何利用C语言实现绘制可爱的橘子钟表,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
    2022-12-12
  • C语言判断字符串长度的方法小结

    C语言判断字符串长度的方法小结

    学过C/C++的人都知道,在C/C++中并没有提供直接获取数组长度的函数,对于存放字符串的字符数组提供了一个strlen函数获取其长度,那么对于其他类型的数组如何获取他们的长度呢?本文给大家介绍了C语言判断字符串长度的方法小结,需要的朋友可以参考下
    2024-08-08
  • 如何基于C++解决RTSP取流报错问题

    如何基于C++解决RTSP取流报错问题

    这篇文章主要介绍了如何基于C++解决RTSP取流报错问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • 美化你的代码 vb(VBS)代码格式化的实现代码

    美化你的代码 vb(VBS)代码格式化的实现代码

    虽然VB.NET出现很久了,但还有好多人仍然在使用VB6。我在实现一些小功能的时候也喜欢用VB6,毕竟谁都不想每天的美好心情被VS那乌龟般的启动速度影响
    2012-05-05
  • C/C++中CJSON的使用(创建与解析JSON数据)

    C/C++中CJSON的使用(创建与解析JSON数据)

    cJSON是一个超轻巧的JSON解析器,本文主要介绍了C/C++中CJSON的使用(创建与解析JSON数据),具有一定的参考价值,感兴趣的可以了解一下
    2021-09-09
  • udp socket客户端和udp服务端程序示例分享

    udp socket客户端和udp服务端程序示例分享

    这篇文章主要介绍了udp socket客户端和udp服务端程序示例,需要的朋友可以参考下
    2014-03-03
  • C语言中数据的存储详解

    C语言中数据的存储详解

    这篇文章主要介绍了C语言中数据的存储详解的相关资料,需要的朋友可以参考下
    2023-08-08
  • C/C++ 编译器优化介绍

    C/C++ 编译器优化介绍

    这篇文章主要涉及了C/C++ 编译器优化的简单介绍,具有一定参考价值。如有不对之处,欢迎指出。
    2017-09-09
  • C语言算法练习之数组元素排序

    C语言算法练习之数组元素排序

    这篇文章主要为大家介绍了C语言算法练习中数组元素排序的实现方法,文中的示例代码讲解详细,对我们学习C语言有一定帮助,需要的可以参考一下
    2022-09-09
  • C语言实现销售管理系统设计

    C语言实现销售管理系统设计

    这篇文章主要为大家详细介绍了C语言实现销售管理系统设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03

最新评论