c语言 链表基本操作

article/2025/10/5 19:42:25

 对于c语言的单链表来说,应该是数据结构中比较简单的一类结构,我们只要认识链表结构,对指针和结构体掌握好,其实编写代码并不算太难。

链表结构:

 对于链表中的每一个结点,我们可以定义如下的结构体:

 基本操作:

1.创造结点:

 为新节点newnode动态开辟一块空间,结点值为x,指针域指向NULL

2.头插结点:

 在进行头插元素的时候,第一步和第二步不能进行交换,如果先进pre->next=s,此时pre->next指向了s,在进行s->next=pre->next,就会使s->next指向自己本身,无法达到预期效果

3.头删结点:

 直接将头指针指向原来指向的下一个位置,即pplist->next=cur->next

4.尾插:

 当链表为空时,直接将pplist指针指向这个新结点即可;当链表不为空时,则需循环遍历链表,找到链表中最后一个结点,然后将其的next域指向新节点,即cur->next=newnode,此时,不需要将新节点的next域赋值为空,因为在创建结点函数中已将next域赋值为空

5.尾删:

 

当链表中只有一个结点时候,直接将其free掉;当链表中有多个结点时,用俩个指针依次向后遍历,直到快指针的next为空,此时慢指针指向链表中倒数第二个节点,直接将其指向空即可。

5.任意位置后插入元素:

 给定一个位置pos,在其后面插入新节点,这种情况与头插法类似,只是在链表中间进行头插,只需要按照头插法的方法即可。

6.任意位置后删除元素:

 对于这种情况,同样是给定一个位置,如果此位置为空或者它的next为空,则无法删除,直接返回;如果给定位置正常,则直接将给定位置的next指向,给定位置的next的next。

 7.查找元素:

在查找元素的时候,只需遍历一遍链表,找到链表当中值与要查找的值相同的结点,并返回(注意,链表中各节点值不相同)。

完整代码: 

SList.h#pragma once
typedef int DateType;
typedef struct SListNode
{DateType data;struct SListNode* next;
}SListNode;// 动态申请一个结点
SListNode* BuySListNode(DateType x);
// 单链表打印
void SListPrint(SListNode* plist);
// 单链表尾插
void SListPushBack(SListNode** pplist, DateType x);
// 单链表的头插
void SListPushFront(SListNode** pplist, DateType x);
// 单链表的尾删
void SListPopBack(SListNode** pplist);
// 单链表头删
void SListPopFront(SListNode** pplist);
// 单链表查找
SListNode* SListFind(SListNode* plist, DateType x); 
// 单链表在pos位置之后插入x
SListNode* SListInsertAfter(SListNode* pos, DateType x);
// 单链表删除pos位置之后的值
SListNode* SListEraseAfter(SListNode* pos);
//销毁单链表
void SListDestory(SListNode** pplist);
//统计链表元素个数
int SListSize(SListNode* plist);void Test();
SList.c#include"SList.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//创造结点
SListNode* BuySListNode(DateType x)
{SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));if (newnode == NULL){exit(0);}newnode->data = x;newnode->next = NULL;return newnode;
}
//尾插
void SListPushBack(SListNode** pplist, DateType x)
{assert(pplist != NULL);if (NULL == *pplist){*pplist = BuySListNode(x);}else{// pplist的链表不为空// 1. 找到原链表中的最后一个节点SListNode* cur = *pplist;while (cur->next){cur = cur->next;}// 2. 插入新节点cur->next = BuySListNode(x);}
}
//尾删
void SListPopBack(SListNode** pplist)
{assert(pplist != NULL);//1.链表中午结点if (NULL == *pplist)return;else if (NULL == (*pplist)->next){// 2. 链表中只有一个节点free(*pplist);*pplist = NULL;}else{// 3. 链表中有多个节点(至少是2个)// a. 找到最后一个节点并保存其前一个节点SListNode* cur = *pplist;SListNode* prev = NULL;   // 保存cur的前一个节点while (cur->next){prev = cur;cur = cur->next;}// cur是最后一个节点   prev刚好是cur的前一个free(cur);prev->next = NULL;/*方法二:1. 找到链表倒数第二个节点while(cur->next->next){cur = cur->next;}// 2. 删除最后一个节点;cur刚好是最后一个节点的前一个节点free(cur->nexr);cur->next = NULL;*/}}
//头插
void SListPushFront(SListNode** pplist, DateType x)
{assert(pplist != NULL);//创造一个新结点SListNode* newnode = BuySListNode(x);newnode->next = *pplist;*pplist = newnode;}
//头删
void SListPopFront(SListNode** pplist)
{assert(pplist != NULL);if (*pplist == NULL){printf("链表为空!!!\n");return;}else{SListNode* cur = *pplist;*pplist = cur->next;free(cur);cur = NULL;}
}
SListNode* SListInsertAfter(SListNode* pos, DateType x)
{if (pos){return;}SListNode* newnode = BuySListNode(x);newnode->next = pos->next;pos->next = newnode;
}
SListNode* SListEraseAfter(SListNode* pos)
{if (pos||pos->next){return;}SListNode* p = pos->next;pos->next = p->next;free(p);p = NULL;
}
//查找元素
SListNode* SListFind(SListNode* plist, DateType x)
{SListNode* cur = plist;while (cur){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}
//统计链表的元素个数
int SListSize(SListNode* plist)
{SListNode* cur = plist;int count = 0;while (cur){count++;cur = cur->next;}return count;
}
//销毁链表
void SListDestory(SListNode** pplist)
{assert(pplist != NULL);SListNode* cur = *pplist;while (cur){*pplist = cur->next;free(cur);cur = *pplist;}*pplist = NULL;
}
//打印单链表
void SListPrint(SListNode* plist)
{SListNode* p = plist;while (p != NULL){printf("%d---->", p->data);p = p->next;}printf("NULL\n");
}void Test()
{SListNode* s =NULL;SListPushBack(&s,1);SListPushBack(&s, 2);SListPushBack(&s, 3);SListPushBack(&s, 4);SListPushBack(&s, 5);SListPopBack(&s);SListPushFront(&s, 4);SListPushFront(&s, 3);SListPushFront(&s, 2);SListPushFront(&s, 1);SListPrint(s);int num=SListSize(s);printf("\nnum=%d\n", num);SListDestory(&s);
}
SList_Main.c#include"SList.h"int main()
{Test();return 0;
}

 


http://chatgpt.dhexx.cn/article/puK2fKPZ.shtml

相关文章

C语言——反转链表

大家好&#xff0c;本人第一次发布博客&#xff0c;目前正在学习数据结构&#xff0c;写博客的目的是一是想分享自己的学习过程&#xff0c;二也是每次写完代码后进行总结。希望大家一起共同学习&#xff01; 现在我正在看《大话数据结构》这本书&#xff0c;每次学习过后我都会…

C语言数据结构之链表

前面的文章我们就一直说&#xff0c;学一个新东西之前一定要弄明白它的作用是什么&#xff0c;我们为什么要用它。之前讲C语言时我们讲到数组&#xff0c;数组的实质是一种顺序储存、随机访问、存储单元连续的线性表&#xff0c;既然存储单元连续&#xff0c;那么对其进行插入和…

C语言来实现链表创建

链表原理理解 链表作为一种线性数据&#xff0c;通过前后节点的指针指向&#xff0c;将所有数据串联起来。为了实现链表数据域的整体耦合&#xff0c;需要额外的指针域来标定前后数据的连接。通过下面的链表结构图&#xff0c;可以非常容易的理解链表的组成结构 头节点作为链表…

链表C语言和C++两种方式实现

一、C语言版本链表&#xff1a; 方向1&#xff1a;无表头 法一&#xff1a;尾插法 #include<stdio.h> #include<malloc.h> //打印 创建 释放 删除某个数 插入某个数 &#xff08;T_T&#xff09;5个功能 struct Node {int data;struct Node* next; }; typedef st…

C语言实现链表创建

C语言实现链表的创建 链表:是一种物理存储单元上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点链表中每一个元素称为结点&#xff09;组成&#xff0c;结点可以在运行时动态生成。每个结点包括两个部分&#xf…

链表(c语言实现)

1.链表的分类 实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; &#xff08;1&#xff09;单向或者双向 &#xff08;2&#xff09;带头或者不带头 &#xff08;3&#xff09;循环或者非循环 虽然有这么多的链表的结构&#xff0c;但是我们…

用c语言写链表

链表是数据结构的一种&#xff0c;是其他三个数据结构栈&#xff0c;树&#xff0c;图的基础&#xff0c;只有将链表这一数据结构弄懂&#xff0c;才能理解其他三种数据结构。 举一个例子&#xff0c;老师让你设计一个联系人系统&#xff0c;其中包括姓名&#xff0c;电话号&am…

C语言链表超详解

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;玩转数据结构 &#x1f4ac;保持…

C语言——链表简单介绍

一、链表的引入 我们至少可以通过两种结构存储数据。 数组&#xff1a;数组是一个固定长度的存储相同数据类型的数据结构&#xff0c;数组中的元素被存储在一段连续的内存空间中。 优点&#xff1a;存取速度快。 缺点&#xff1a;需要一个连续的很大的内存&#xff1b; 插入和…

c语言链表示例

链表是一种常见的基础数据结构&#xff0c;结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配&#xff0c;也就是说&#xff0c;链表是一个功能极为强大的数组&#xff0c;他可以在节点中定义多种数据类型&#xff0c;还可以根据需要随意增添&#xff0c;删除&…

反转链表c语言

反转链表 初始化三个指针 循环执行 temp cur→next cur→next pre pre cur ; cur temp 对于单链表&#xff0c;所有操作都是从头指针开始 // An highlighted block struct ListNode* ReverseList(struct ListNode* pHead ) {// 三指针法struct ListNode* pre pHead;s…

链表C语言实现--单向链表

线性结构的链式存储也称为链表&#xff0c;相比于顺序表&#xff0c;链表能够解决顺序表中空间资源浪费问题以及空间不足的问题。链表的每一个结点包含数据域和指针域&#xff0c;而每一个结点在内存中的地址是不连续的&#xff0c;且能适应动态变化。在数据插入和数据删除操作…

循环链表C语言实现

本文介绍循环链表中的单向循环链表&#xff0c;双向循环链表两种 第一种&#xff1a;单向循环链表&#xff0c;是在单向链表的基础上&#xff0c;尾结点不再指向NULL&#xff0c;而是指向头结点从而构成循环。如下图&#xff1a; 所以相比单向链表最大的特点就是可以从尾快速循…

C语言基础入门:链表详解篇

链表概述 链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一个“头指针”变量&#xff0c;以head表示&#xff0c;它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”&#xff0c;每个结点都应包括两个…

C语言——基础链表详解

敢于向黑暗宣战的人&#xff0c;心里必须充满光明。 一、链表的构成 1.构成 链表是由一连串的结构&#xff08;称为结点&#xff09;组成的。 (1)结点的构成&#xff1a; 数据&#xff08;要储存的数据&#xff09;指针&#xff08;指向下一个结点的指针&#xff09; (2)关…

C语言数据结构——链表

目录 前言 一、什么是链表 1.1链表的结构和概念 1.2 链表的分类 二、无头单向非循环链表 2.1 创建结构体 2.2 动态申请一个节点 2.3 单链表打印 2.4 单链表尾插/尾删 2.4.1 单链表尾插 2.4.2 单链表尾删 2.5 单链表头插/头删 2.5.1 头插 2.5.2 头删 2.6 单链表查…

C语言链表详解(通俗易懂)

文章目录 前言一、什么是线性表&#xff1f;二、顺序表&#xff1a;三、链表&#xff1a;四、顺序表和链表对比&#xff1a;总结 前言 线性表是实际中广泛应用的重要数据结构&#xff0c;本文用通俗易懂的方法讲解它。 一、什么是线性表&#xff1f; 首先&#xff0c;我们了解…

C语言——链表

C语言——链表 链表是一种基础的数据结构类型&#xff0c;一种能够动态维护数据的线性数据表。链表的数据以结点形式存储信息&#xff0c;并通过结点之间的指针实现结点之间的衔接。 为什么要用链表&#xff1f; 链表和数组类似&#xff0c;但是功能比数组强大得多&#xff0c…

在?您的rsyslog日志管理手册到了,请查收

rsyslog日志管理和logrotate日志存储轮转 前言&#xff1a; 系统日志是记录服务器系统运行和软件运行状况的记录程序&#xff0c;如果系统和软件在运行中出错&#xff0c;我们就可以在日志中获取到问题发生时的记录&#xff0c;并以此寻求解决问题的方法。 一.rsyslog 系统日…

日志审计与分析实验三(rsyslog服务器端和客户端配置)(Linux日志收集)

文章目录 Linux日志收集一、实验目的&#xff1a;1、掌握rsyslog配置方法2、配置rsyslog服务收集其他Linux服务器日志: 二、实验步骤&#xff1a;1、前期配置2. rsyslog的三种传输协议1、udp传输方式2、tcp传输方式3、relp传输方式 Linux日志收集 一、实验目的&#xff1a; 1…