广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言单链表的图文示例讲解
  • 247
分享到

C语言单链表的图文示例讲解

C语言单链表的基本操作C语言单链表 2023-02-14 15:02:49 247人浏览 独家记忆
摘要

目录一、单链表的结构二、单链表的函数接口1. 申请结点及打印单链表2. 尾插尾删3. 头插头删4. 中间插入和删除1. 在 pos 指向的结点之后插入结点2. 在 pos 指向的结点

在上一篇所讲述的 动态顺序表 中存在一些缺陷

1、当空间不够时需要扩容,扩容是有一定的消耗的

如果每次空间扩大一点,可能会造成空间的浪费,而空间扩小了,又会造成频繁的扩容2、在顺序表中进行头部和中部的插入时需要移动数据,效率低下

对于顺序表的这些缺陷,有如下解决方案

1、需要时申请一块空间,不需要时将其释放

2、插入删除不需要移动数据

而链表就符合这两点,本篇介绍 无头单向非循环链表(单链表)

一、单链表的结构

空链表: 此时没有存储数据,只有一个指针指向 NULL

以上便是单链表的结构:

  • 每一块空间可以按需申请释放
  • 插入和删除不需要移动数据,修改每块空间的指针指向即可

在习惯上将申请的一块一块的空间称为结点,指向第一个结点的指针称为头指针

//数据的类型:这里以 int 来举例
typedef int SLTDataType;
//结点的类型
typedef struct SListnode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

二、单链表的函数接口

1. 申请结点及打印单链表

在插入时需要申请结点,为了避免麻烦重复的操作,这里将申请结点封装为一个函数

申请结点函数如下:

SLTNode* BuySLTNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if(newnode == NULL)
	{
		//开辟空间失败,打印错误信息
		perror("malloc");
		//结束程序
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

为了验证插入、删除等得到的结果是否正确,提供打印单链表的函数,这里数据类型以 int 为例,当读者采用的类型不同时,自行更改函数即可

打印单链表函数如下:

void SLTPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	//打印数据
	while(cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

2. 尾插尾删

尾插:在链表的最后一个结点之后插入结点

尾插函数如下:

//在链表为空时,需要改变头指针,这里采用传二级指针的方式
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	//申请结点
	SLTNode* newnode = BuySLTNode(x);
	//链表为空时
	if(*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		//找到最后一个结点
		SLTNode* ptail = *pphead;
		while(ptail->next)
		{
			ptail = ptail->next;
		}
		ptail->next = newnode;
	}
}

尾删:删除链表最后一个结点

尾删函数如下:

//链表只有一个结点时,需要改变头指针,这里采用传二级指针的方式
void SLTPopBack(SLTNode** pphead)
{
	//链表为空时,无法删除
	assert(*pphead);
	//链表只有一个结点时
	if((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		//找到倒数第二个结点
		SLTNode* ptail = *pphead;
		while(ptail->next->next)
		{
			ptail = ptail->next;
		}
		free(ptail->next);
		ptail->next = NULL;
	}
}

3. 头插头删

头插: 在第一个结点之前插入新结点

头插函数如下:

//需要改变头指针,这里采用传二级指针的方式
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	//申请结点
	SLTNode* newnode = BuySLTNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

头删:删除链表的第一个结点

头删函数如下:

//需要改变头指针,这里采用传二级指针的方式
void SLTPopFront(SLTNode** pphead)
{
	//链表为空时,无法删除
	assert(*pphead);
	//保存第二个结点
	SLTNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

4. 中间插入和删除

中间插入:通过后面介绍的查找函数 SLTFind 获得指向结点的指针 pos,在 pos 指向的 结点之前 或 之后 插入结点

1. 在 pos 指向的结点之后插入结点

在 pos 之后插入结点函数如下:

void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	//pos 不能为空
	assert(pos);
	//申请结点
	SLTNode* newnode = BuySLTNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

2. 在 pos 指向的结点之前插入结点

在 pos 之前插入结点函数如下:

//pos 指向头结点时,需要改变头指针,这里采用传二级指针的方式
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	//pos 不能为空
	assert(pos);
	//头插
	if(*pphead == pos)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		//找到 pos 的前一个结点
		SLTNode* prev = *pphead;
		while(prev->next != pos)
		{
			prev = prev->next;
		}
		//申请结点
		SLTNode* newnode = BuySLTNode(x);
		newnode->next = pos;
		prev->next = newnode;
	}
}

中间删除:通过后面介绍的查找函数 SLTFind 获得指向结点的指针 pos,删除 pos 指向的结点 或 后一个结点

3. 删除 pos 指向的结点的后一个结点

删除 pos 之后的结点函数如下:

void SLTEraseAfter(SLTNode* pos)
{
	//pos 不能为空
	assert(pos);
	//指向最后一个结点时,不做处理
	if(pos->next == NULL)
	{
		return;
	}
	else
	{
		//保存后一个结点
		SLTNode* next = pos->next;
		pos->next = next->next;
		free(next);
	}
}

4. 删除 pos 指向的结点

删除 pos 指向的结点函数如下:

//pos 指向头结点时,需要改变头指针,这里采用传二级指针的方式
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	//pos 不能为空
	assert(pos);
	//头删
	if (*pphead == pos)
	{
		SLTPopFront(pphead);
	}
	else
	{
		//找到 pos 的前一个结点
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}

6. 查找

查找:如果数据存在,返回该数据结点的指针,不存在返回 NULL

查找函数如下:

SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
	SLTNode* cur = phead;
	//查找
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

7. 销毁单链表

在单链表中,存储数据的结点是由自己开辟的,当不使用单链表时,应将其销毁

销毁单链表函数如下:

需要将头指针置空,这里采用传二级指针的方式
void SLTDestroy(SLTNode** pphead)
{
	SLTNode* cur = *pphead;
	while (cur)
	{
		//保存下一个结点
		SLTNode* nextnode = cur->next;
		free(cur);
		cur = nextnode;
	}
	//将头指针置空
	*pphead = NULL;
}

到此这篇关于C语言单链表的图文示例讲解的文章就介绍到这了,更多相关C语言单链表 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言单链表的图文示例讲解

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言单链表的图文示例讲解
    目录一、单链表的结构二、单链表的函数接口1. 申请结点及打印单链表2. 尾插尾删3. 头插头删4. 中间插入和删除1. 在 pos 指向的结点之后插入结点2. 在 pos 指向的结点...
    99+
    2023-02-14
    C语言单链表的基本操作 C语言单链表
  • C语言中单链表的示例分析
    这篇文章将为大家详细讲解有关C语言中单链表的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、思路步骤1. 定义结构体a.数据域:用来存放数据b.指针域:用来存放下一个数据的位置2.初始化申请头结...
    99+
    2023-06-25
  • C语言数据结构实例讲解单链表的实现
    目录1、单链表2、单链表的实现头文件函数的实现(1)打印链表(2)动态申请结点(3)尾插(4)头插(5)尾删(6)头删(7)查找(8)在pos之前插入(9)删除pos(10)在pos...
    99+
    2022-11-13
  • C语言单链表遍历与求和示例解读
    目录单链表的遍历单链表的求和单链表的遍历 描述: 牛牛从键盘输入一个长度为 n 的数组,问你能否用这个数组组成一个链表,并顺序输出链表每个节点的值。 输入描述: 第一行输入一个正整数...
    99+
    2022-11-13
  • C语言链表与单链表详解
    链表是什么及链表的优势 链表是一种介于数组的另外一种数据结构: 我们知道数组可以存放很多的元素,这些元素都是呈线性排列,也就是一个挨着一个连续存放 但是当元素足够多时,还能继续正常的...
    99+
    2022-11-13
  • C语言单链表实例分析
    今天小编给大家分享一下C语言单链表实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1、移除链表元素链接直达:移除链表元...
    99+
    2023-06-30
  • C语言实题讲解快速掌握单链表上
    目录1、移除链表元素2、反转链表3、链表的中间节点4、链表中倒数第k个节点5、合并两个有序链表6、链表分割1、移除链表元素 链接直达: 移除链表元素 题目: 思路: 此题要综合考虑...
    99+
    2022-11-13
  • C语言实题讲解快速掌握单链表下
    目录1、移除链表元素2、反转链表3、链表的中间节点4、链表中倒数第k个节点5、合并两个有序链表6、链表分割1、移除链表元素 链接直达: 移除链表元素 题目:  思路: 此...
    99+
    2022-11-13
  • 详解C语言之单链表
    目录一、思路步骤1. 定义结构体2.初始化3.求当前数据元素的个数4.插入5.删除6.释放内存空间二、代码总结 一、思路步骤 1. 定义结构体 a.数据域:用来存放数据 b.指针域...
    99+
    2022-11-12
  • C语言深入讲解链表的使用
    目录一、链表的概念二、链表的分类1. 单向或者双向链表2. 带头或者不带头(是否有自带哨兵位头结点)3. 循环或者非循环链表4. 无头单向非循环链表和带头双向循环链表3、链表的实现(...
    99+
    2022-11-13
  • C语言实现无头单向链表的示例代码
    目录一、易错的接口实现 1.1 新节点开辟函数 1.2 尾插 1.3 尾删 二、常见简单接口 2.1 打印链表 2.2 节点计数器 2.3 判断是否为空链表 2.4 通过值查找节点 ...
    99+
    2022-11-12
  • C语言数据结构超详细讲解单向链表
    目录1.链表概况1.1 链表的概念及结构1.2 链表的分类2. 单向链表的实现2.1 SList.h(头文件的汇总,函数的声明)2.2 SList.c(函数的具体实现逻辑)2.2.1...
    99+
    2022-11-13
  • C语言实例真题讲解数据结构中单向环形链表
    目录1、例题引入2、何为带环链表3、题解思路4、拓展问题目录 1、例题引入 链接直达: 环形链表 题目: 2、何为带环链表  正常的单链表每个节点顺次链接,最后一个节点指...
    99+
    2022-11-13
  • C语言示例讲解ifelse语句的用法
    目录1、前言2、if语句的语法结构3、关于if else语句的示例4、if else 书写形式的对比5、例子1、前言 (1)C语言是结构化的程序设计语言。C语言的三种基本程序结构分别...
    99+
    2022-11-13
  • C语言超详细i讲解双向链表
    目录一、双向链表的概念二、双向链表的实现三、链表与顺序表的差别四、链表oj总结一、双向链表的概念 1、概念:概念:双向链表是每个结点除后继指针外还有⼀个前驱指针。双向链表也有带头结点...
    99+
    2022-11-13
  • C语言实现线性动态(单向)链表的示例代码
    目录什么是链表为什么不用结构体数组链表的操作创建表删除元素插入元素代码及运行结果什么是链表 链表是数据结构里面的一种,线性链表是链表的一种,线性链表的延伸有双向链表和环形链表。在编程...
    99+
    2022-11-13
  • C语言实现链表与文件存取的示例代码
    目录此处为main函数的内容一、输入数据到链表中二、把链表数据存入文件三、输出文件完整代码本程序主要功能是建立链表,然后把链表数据存储到文件中,然后把文件数据存储到数组中并输出。 不...
    99+
    2022-11-13
  • C语言实现动态链表的示例代码
    目录结构体定义已经函数声明函数实现创建一个链表判断链表是否为空获得链表中节点的个数在某个特定的位置插入一个元素获得指定下标的节点的元素删除一个节点链表逆序链表的清空链表的销毁链表的遍...
    99+
    2022-11-13
  • C语言示例讲解for循环的用法
    目录1、循环语句for的语法2、for循环中的break以及continue3、for语句的循环变量控制的一些建议4、for循环的变种5、题目1、循环语句for的语法 for (表达...
    99+
    2022-11-13
  • C语言实现无头单链表详解
    目录链表的结构体描述(节点)再定义一个结构体(链表) 断言处理 & 判空处理创建链表创建节点头插法打印链表尾插法 指定位置插入 头删法尾删法&n...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作