返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言无头单向非循环链表的操作方法有哪些
  • 368
分享到

C语言无头单向非循环链表的操作方法有哪些

2023-06-30 09:06:42 368人浏览 八月长安
摘要

这篇文章主要介绍“C语言无头单向非循环链表的操作方法有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C语言无头单向非循环链表的操作方法有哪些”文章能帮助大家解决问题。链表引入问:上次我们看了顺序

这篇文章主要介绍“C语言无头单向非循环链表的操作方法有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C语言无头单向非循环链表的操作方法有哪些”文章能帮助大家解决问题。

链表引入

问:上次我们看了顺序表,那么顺序表有些什么优缺点呢?

优点:

顺序表是连续的物理空间,方便下标的随机访问。

缺点:

增容需要申请新空间,拷贝数据,释放旧的空间。会有一定消耗。

头部或者中间位置插入或者删除数据,需要挪动数据,效率较低。

可能存在一定空间占用,浪费空间,不能按需申请和释放空间。

为了解决上诉问题,我们引入了链表。首先我们先来看看单链表。

链表介绍

链表是一种物理存储结构上非连续、非顺序的存储结构、数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个节点包含两部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

C语言无头单向非循环链表的操作方法有哪些

实际上,链表的结构多样,如下:

单向或者双向

C语言无头单向非循环链表的操作方法有哪些

带头或者不带头

C语言无头单向非循环链表的操作方法有哪些

循环或者非循环

C语言无头单向非循环链表的操作方法有哪些

创建链表

链表是由结点链接而成的,所以创建链表需要创建一个结点类型。该类型由指针域和数据域组成。

typedef int SLTDataType;typedef struct SListnode{SLTDataType data;//用来存放该结点的数据struct SListNode* next;//用来存放下一个结点的地址}SListNode;

打印链表

从头指针指向的位置开始,依次向后打印,知道cur访问到NULL就结束循环。

C语言无头单向非循环链表的操作方法有哪些

void SListPrint(SListNode* phead);void SListPrint(SListNode* phead){SListNode* cur = phead;//我们一般不会改变头指针,所以我们把头指针赋值给curwhile (cur)//链表结束条件{printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");//表示数据已经打印完毕}

创建结点

每当我们需要插入一个数据,我们就需要申请一个结点,如果每次都重新申请就会很麻烦,所以我们将创建一个新结点封装为一个函数。

SListNode* BuySListNode(SLTDataType x){SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));if (newnode == NULL){printf("BuySListNode::%s\n", strerror(errno));//若申请失败,则打印错误信息exit(-1);}else{newnode->data = x;//将数据赋值到新点的数据域newnode->next = NULL;//新结点指针域置为空指针}return newnode;//返回新结点的地址}

单链表尾插

我们需要将尾插分为两种情况:

情况一: 链表为空,我们直接让头指针指向新的结点即可。

情况二: 链表已经有多个结点,我们需要找到链表的最后一个结点,然后让最后一个结点指向新的结点。

void SListPushBack(SListNode** pphead, SLTDataType x);void SListPushBack(SListNode** pphead, SLTDataType x){assert(pphead);SListNode* newnode = BuySListNode(x);//链表为空if (*pphead == NULL){*pphead = newnode;//头指针指向新的结点}//链表不为空else{SListNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}}

注意: 链表头插函数的参数我们应该传头指针的地址,而不是头指针本身。如果为传值调用,那么形参是实参的一份临时拷贝,对形参的改变不会影响实参。

单链表头插

单链表头插时,我们申请一个新的结点,然后让新结点的指针域指向之前的第一个结点,然后让头指针指向新结点。

注意:这两步操作的顺序不可以颠倒,如果先让头指针指向了新结点,那么将不可能找到第一个结点的位置了。也不可能在找到后面的数据了。

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

单链表尾删

演示一种错误的写法:

C语言无头单向非循环链表的操作方法有哪些

对于单链表的尾删,我们需要考虑三种情况:

链表为空时,不做任何处理。

链表只有一个结点时,释放该结点,然后将头指针置为空。

链表有多个结点时,有两种处理方法,详见一下代码。

C语言无头单向非循环链表的操作方法有哪些

代码一: 找到最后一个结点的前一个结点,释放最后一个结点。将前一个结点的指针域置为空指针。

void SListPopBack(SListNode** pphead);void SListPopBack(SListNode** pphead){assert(pphead);if (*pphead == NULL)return;else if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SListNode* prev = NULL;SListNode* tail = *pphead;while (tail->next != NULL){prev = tail;tail = tail->next;}free(tail);tail = NULL;prev->next = NULL;}}

代码二: 找到最后一个结点的前一个结点,将后一个结点释放掉,然后在置为空就可以了。

void SListPopBack(SListNode** pphead);void SListPopBack(SListNode** pphead){assert(pphead);if (*pphead == NULL)return;else if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SListNode* tail = *pphead;while (tail->next->next != NULL){tail = tail->next;}free(tail->next);tail->next = NULL;}}

单链表头删

若链表为空,则不处理。若链表不为空,让头指针指向第二个结点,释放掉第一个结点。

void SListPopFront(SListNode** pphead);void SListPopFront(SListNode** pphead){assert(pphead);if (*pphead == NULL)//链表为空return;else{SListNode* head = *pphead;*pphead = head->next;//让头指针指针域中的地址指向头指针free(head);//释放第一个结点head = NULL;}}

在pos位置之前插入数据

若pos是第一个结点,我们直接调用之前写的头插。若pos不是第一个结点,我们找到pos位置的前一个结点,让新的结点指向地址为pos的结点,然后让前一个结点指向新结点。

C语言无头单向非循环链表的操作方法有哪些

void SListInsertBefore(SListNode** pphead, SListNode* pos, SLTDataType x);void SListInsertBefore(SListNode** pphead, SListNode* pos, SLTDataType x){assert(pphead);assert(pos);if (*pphead == pos){SListPushFront(pphead,x);//头插函数}else{SListNode* prev = *pphead;while (prev->next != pos)//找到pos的前一个结点{prev = prev->next;}SListNode* newnode = BuySListNode(x);newnode->next = prev->next;//让新结点指向pos结点prev->next = newnode;//让前一个结点指向新结点}}

在pos位置之后插入数据

让新结点指向该位置的下一个位置,然后让该位置的结点指向新结点。

C语言无头单向非循环链表的操作方法有哪些

void SListInsertAfter(SListNode** pphead, SListNode* pos, SLTDataType x);void SListInsertAfter(SListNode** pphead, SListNode* pos, SLTDataType x){assert(pphead);SListNode* newnode = BuySListNode(x);newnode->next = pos->next;pos->next = newnode;}

删除pos位置结点

C语言无头单向非循环链表的操作方法有哪些

void SListErase(SListNode** pphead, SListNode* pos);void SListErase(SListNode** pphead, SListNode* pos){assert(pphead);assert(pos);if (*pphead == pos){SListPopFront(pphead);}else{SListNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}}

删除pos位置之后的结点

C语言无头单向非循环链表的操作方法有哪些

void SListEraseAfter(SListNode* pos);void SListEraseAfter(SListNode* pos){assert(pos);SListNode* next = pos->next;if (next)//如果next不为空,则条件为真{pos->next = next->next;//让pos指向要删除位置的后一个结点free(next);//释放pos的下一个结点next = NULL;}}

销毁链表

在销毁链表时。首先我们将头指针赋值给一个新的指针,用该指针依次遍历链表,先把该结点的下一个结点的地址保存,然后在释放该结点,最后将头指针置为空。

注意: 一定要在释放该指针之前保存该指针的下一个结点的地址,否则就找不到下一个结点了。

void SListDestroy(SListNode** pphead);void SListDestroy(SListNode** pphead){assert(pphead);SListNode* cur = *pphead;while (cur){SListNode* next = cur->next;//存放下一个结点地址free(cur);//释放当前结点cur = NULL;}*pphead = NULL;//将头指针置为空}

链表查找

SListNode* SListFind(SListNode* phead, SLTDataType x);SListNode* SListFind(SListNode* phead, SLTDataType x){SListNode* cur = phead;while (cur != NULL){if (cur->data == x){return cur;}cur = cur->next;}return NULL;}

关于“C语言无头单向非循环链表的操作方法有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网其他教程频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: C语言无头单向非循环链表的操作方法有哪些

本文链接: https://lsjlt.com/news/327950.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C语言无头单向非循环链表的操作方法有哪些
    这篇文章主要介绍“C语言无头单向非循环链表的操作方法有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C语言无头单向非循环链表的操作方法有哪些”文章能帮助大家解决问题。链表引入问:上次我们看了顺序...
    99+
    2023-06-30
  • C语言详解无头单向非循环链表各种操作方法
    目录链表引入链表介绍创建链表打印链表创建结点单链表尾插单链表头插单链表尾删单链表头删在pos位置之前插入数据在pos位置之后插入数据删除pos位置结点删除pos位置之后的结点销毁链表...
    99+
    2024-04-02
  • C语言 超详细介绍与实现线性表中的无头单向非循环链表
    目录一、本章重点二、链表介绍三、无头单向非循环链表常用接口实现3.1动态申请一个节点3.2单链表打印3.3单链表尾插3.4单链表的头插3.5单链表的尾删3.6单链表头删3.7单链表查...
    99+
    2024-04-02
  • C语言链表的操作有哪些
    这篇“C语言链表的操作有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C语言链表的操作有哪些”文章吧。前言编译工具:vs...
    99+
    2023-06-30
  • C语言实现带头双向循环链表的接口
    本文实例为大家分享了C语言实现带头双向循环链表的接口,供大家参考,具体内容如下 各函数功能如下 申请空间 ListNode* BuyListNode(LTDataType x) ...
    99+
    2024-04-02
  • C语言带头双向循环链表的示例代码
    目录前言结构分析链表的基本操作实现创建节点初始化链表链表销毁打印链表链表尾插链表尾删链表头插链表头删链表查找链表pos位置前面去插入删除pos位置链表判空代码复用总代码及头文件前言 ...
    99+
    2022-11-13
    C语言带头双向循环链表 C语言 双向循环链表 C语言 循环链表
  • C语言实现无头单向链表的示例代码
    目录一、易错的接口实现 1.1 新节点开辟函数 1.2 尾插 1.3 尾删 二、常见简单接口 2.1 打印链表 2.2 节点计数器 2.3 判断是否为空链表 2.4 通过值查找节点 ...
    99+
    2024-04-02
  • C语言循环链表的原理与使用操作
    目录一.引入二.循环链表的定义三.单链表与循环链表对比3.1图示对比3.2代码对比四.循环链表的操作4.1循环链表的初始化4.2循环链表的建立4.2.1头插法建立循环链表4.2.2尾...
    99+
    2024-04-02
  • C语言怎么实现线性表中的带头双向循环链表
    这篇文章主要介绍了C语言怎么实现线性表中的带头双向循环链表的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言怎么实现线性表中的带头双向循环链表文章都会有所收获,下面我们一起来看看吧。一、本章重点带头双向循环链...
    99+
    2023-06-29
  • ​​​​​​​C语言实现单链表基本操作方法
    目录存储结构基本功能头插法创建单链表尾插法创建单链表获取指定位置的元素在指定位置插入元素删除指定位置的元素获取单链表的长度合并两个非递减的单链表晴链表遍历打印单链表附上完整代码存储结...
    99+
    2024-04-02
  • C++中检测链表中的循环方法有哪些
    这篇文章主要讲解了“C++中检测链表中的循环方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++中检测链表中的循环方法有哪些”吧!给定一个链表,检查链表是否有循环。下图显示了带有循...
    99+
    2023-06-15
  • es6循环操作的方法有哪些
    这篇“es6循环操作的方法有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“es6循环操...
    99+
    2024-04-02
  • java数据结构单向链表的操作有哪些
    本文小编为大家详细介绍“java数据结构单向链表的操作有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“java数据结构单向链表的操作有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。关于节点数据添加:尾添...
    99+
    2023-07-06
  • C语言超详细介绍与实现线性表中的带头双向循环链表
    目录一、本章重点二、带头双向循环链表介绍2.1什么是带头双向循环链表?2.2最常用的两种链表结构三、带头双向循环链表常用接口实现 3.1结构体创建3.2带头双向循环链表的初始化 3....
    99+
    2024-04-02
  • C语言文件的操作方法有哪些
    这篇文章主要讲解了“C语言文件的操作方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言文件的操作方法有哪些”吧!文件的顺序读写字符输入输出fgetc和fputcfgetc:字符输...
    99+
    2023-06-29
  • C语言数组的操作方法有哪些
    本篇内容主要讲解“C语言数组的操作方法有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言数组的操作方法有哪些”吧!一、一维数组1.创建//如何创建数组int num[10];c...
    99+
    2023-06-30
  • C语言中如何实现单向链表的增删查改操作
    这篇文章主要介绍了C语言中如何实现单向链表的增删查改操作,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言链表是线性表的链式存储结构,它可以以O(1)的时间复杂度进行插入或者...
    99+
    2023-06-25
  • C语言中文件操作方法有哪些
    这篇文章主要介绍了C语言中文件操作方法有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是文件程序文件其实从文件的功能的角度来说:我们的文件可以分为两种类型的文件:程序...
    99+
    2023-06-25
  • C语言中单链表(不带头结点)基本操作的实现详解
    目录一、单链表的概念二、单链表的基本操作1.创建单个结点2.创建具有n个结点的链表3.打印单链表4.尾插5.尾删6.头插7.头删8.查找某个结点9.在某个结点后面插入10.在某个结点...
    99+
    2022-11-16
    C语言单链表操作 C语言单链表
  • C语言中的字符串操作方法有哪些
    本文小编为大家详细介绍“C语言中的字符串操作方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言中的字符串操作方法有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。字符串在C语言里使用非常多,因为很...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作