c语言之链表

news2025/1/11 4:13:24

  今天来介绍一下c语言如何手写一个单向链表,我们都知道链表是用来提高空间的利用效率的数据结构,其中包括了一个数据域和指针域,数据域用来存储数据,指针域用来指向下一个节点。数据结构如下

 

  我们都知道数据结构最主要的是他的增删改查的功能,这边主要介绍五个操作链表的函数

 

SLIST *SList_Create();//创建链表
int SList_Print(SLIST *pHead);//遍历链表
int SList_NodeInsert(SLIST *pHead, int x, int y);//插入值 在x之前插入y 没查找到在尾部插入
int SList_NodeDel(SLIST *pHead, int y);//删除某个结点
int SLIST_Destory(SLIST *pHead);//清除链表

1.首先是创建链表函数:这边主要功能是接收用户的输入然后直到用户输入-1结束链表的创建。下面是思路:需要三个辅助指针变量,即头节点pHead,新节点pM,当前节点pCur

(1)创建头节点

(2)循环接受用户输入创建新节点

(3)当前节点的指针域指向新节点,当前节点指向新节点

2. 遍历链表函数:这边只需要一个辅助指针变量(不需要也可以)

(1)循环遍历链表打印结果,遍历操作使用pCur=pCur->next,pCur->next就是下一个节点

3.插入值函数:需要三个辅助指针变量,即新节点指针变量pM用于创建新节点,pPre指向搜索到的节点的前一个节点,pCur指向搜索到的节点

 

如图所示,插入一个新的节点就是用前一个节点指向新的节点,然后新节点的指针域指向当前节点即可实现。

这边需要注意的是,需要先将新节点指向当前节点,再将前节点指向当前节点。由于只有前节点的指针域指向了后节点,如果先让前结点指向新节点的话就会导致后节点无法找到。

4.删除节点函数:

如图所示,将前一个节点指向当前节点的下一个节点即可,即pPre->next=pCur->next;

5.清除链表函数:遍历释放空间即可

下面是源码分享

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct Node
{
	int data;
	struct Node *next;
}SLIST;

SLIST *SList_Create();//创建链表
int SList_Print(SLIST *pHead);//遍历链表
int SList_NodeInsert(SLIST *pHead, int x, int y);//插入值 在x之前插入y 没查找到在尾部插入
int SList_NodeDel(SLIST *pHead, int y);//删除某个结点
int SLIST_Destory(SLIST *pHead);//清除链表

//创建链表

//思路

//三个辅助指针变量 
//1.创建节点 pM
//2.头节点 pHead
//3.当前结点 pCur
SLIST *SList_Create()
{
	SLIST *pHead = NULL, *pM = NULL, *pCur = NULL;
	int num;

	//创建头节点
	pHead = (SLIST *)malloc(sizeof(SLIST));

	if (pHead == NULL)
	{
		return NULL;
	}

	printf("\nplease enter you number:");
	scanf("%d", &num);

	pCur = pHead;
	while (num != -1)
	{
		//创建新结点
		pM = (SLIST *)malloc(sizeof(SLIST));
		if (pM == NULL)
		{
			return NULL;
		}
		pM->data = num;
		pM->next = NULL;

		pCur->next = pM;
		pCur = pCur->next;

		printf("\nplease enter you number:");
		scanf("%d", &num);
	}

	return pHead;

}

//遍历链表
int SList_Print(SLIST *pHead)
{
	SLIST *pCur = NULL;
	if (pHead == NULL ||pHead->next==NULL)
	{
		printf("list is null\n");
		return -1;
	}

	pCur = pHead->next;
	printf("\nbegin\n");
	while (pCur)
	{
		printf("%d ", pCur->data);
		pCur = pCur->next;
	}
	printf("\nend\n");
	return 0;
}

//插入值 在x之前插入y  

//创建新结点 pM
//利用两个辅助指针变量一前一后,找到要的值后
//先将新结点指向后结点再将头前结点指向新结点
int SList_NodeInsert(SLIST *pHead, int x, int y)
{
	SLIST *pM = NULL, *pPre = NULL, *pCur = NULL;

	pM = (SLIST *)malloc(sizeof(SLIST));
	if (pM == NULL)
	{
		return -1;
	}

	pM->data = y;
	pM->next = NULL;

	pPre = pHead;
	pCur = pHead->next;
	
	while (pCur)
	{
		if (pCur->data == x)
		{
			break;
		}

		pPre = pCur;
		pCur = pCur->next;
	}

	pM->next = pCur;
	pPre->next = pM;
	return 0;
}

//移除某个结点
//两个辅助指针变量
int SList_NodeDel(SLIST *pHead, int y)
{
	SLIST *pPre = NULL, *pCur = NULL;
	pPre = pHead;
	pCur = pHead->next;
	while (pCur)
	{
		if (pCur->data == y)
		{
			break;
		}
		pPre = pCur;
		pCur = pCur->next;
	}

	if (pCur == NULL)
	{
		printf("don't find %d\n", y);
		return -1;
	}

	pPre->next = pCur->next;

	free(pCur);
	return 0;
}

int SLIST_Destory(SLIST *pHead)
{
	SLIST *temp = NULL;
	if (pHead == NULL)
	{
		return -1;
	}
	//pHead = pHead->next;
	temp = pHead->next;
	while (temp)
	{
		free(pHead);
		pHead->next = NULL;
		pHead = temp;
		temp = temp->next;
	}
	
	return 0;
}

int main()
{
	int ret = 0;
	SLIST *headlist = NULL;
	headlist = SList_Create();
	ret = SList_Print(headlist);
	ret = SList_NodeInsert(headlist, 20, 19);
	ret = SList_Print(headlist);
	ret = SList_NodeDel(headlist,19);
	ret = SList_Print(headlist);
	ret = SLIST_Destory(headlist);
	ret = SList_Print(headlist);
	system("pause");
	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/194064.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从底层入手搞定C++引用和内联函数

C引用和内联函数 文章目录C引用和内联函数一、引用1.1引用的概念1.1.1代码展示1.1.2图示1.2引用的特性1.3常引用1.4引用的使用场景1.5 传值、传引用效率比较1.6 引用和指针的区别二、内联函数2.1.内联函数的概念2.2内联函数的特性总结一、引用 首先我们来看一下引用的概念&…

每天10个前端小知识 【Day 2】

前端面试基础知识题 1. arguments 这种类数组&#xff0c;如何遍历类数组&#xff1f; for(var i 0, len arrayLike.length; i < len; i) { …… }使用ES6的 … 运算符&#xff0c;我们可以轻松转成数组。 function func(...arguments) { console.log(arguments); // […

蓝牙和射频技术的关系

蓝牙和射频技术的关系 提到蓝牙大家的比较熟悉&#xff0c;但射频技术很多都没有明白什么意思&#xff1f; 现简单介绍下他们的关系&#xff0c;让想了解射频技术的朋友更清楚。 1&#xff1a;定义&#xff1a; 射频&#xff08;RF&#xff09;是Radio Frequency的缩写&#xf…

Fluent的模型参数化(2)

前言&#xff1a;本文基于2023R1版本。在《Fluent的模型参数化&#xff08;1&#xff09;》中&#xff0c;对将Fluent模型进行参数化的方法进行了概述。本文主要基于已参数化的模型&#xff0c;进行参数分析的方法。基本概念&#xff1a;输入参数&#xff1a;工况的设置数据&am…

SpringMVC之入门案例

目录 一&#xff1a;概述 二代码实操&#xff1a; 步骤1:创建Maven项目&#xff0c;并导入对应的jar包 步骤2:创建控制器类 步骤3:创建配置类 步骤4:创建Tomcat的Servlet容器配置类 步骤5:配置Tomcat环境 步骤6:启动运行项目 步骤7:浏览器访问 知识点1&#xff1a;Co…

Cesium的设计结构与零基础入门

关于cesium我最近会写一系列的文章教程,带大家一步一步的从零开始学习cesium,看过我的文章的人都清楚我的讲课方式就是从一个小白的视角,从一个什么都不懂的视角,一点一点的循序渐进为大家讲清楚一个知识,好废话不多说我们开始! 首先在学习之前,你必须清楚cesium是个什…

DynaSLAM-7 DynaSLAM中双目运行流程(Ⅰ):加载Mask R-CNN网络部分MaskNet.cc

目录 1.执行流程 2. SegmentDynObject::SegmentDynObject 3. SegmentDynObject::GetSegmentation 1.执行流程 我们输入到命令行五个参数&#xff1a; stereo_kitti path_to_vocabulary path_to_settings path_to_sequence (path_to_masks) 分别是DynaSLAM双目例程中的可执行…

血氧仪/额温枪/电子体温计等 LED数显/数码管显示驱动控制电路(IC/芯片)-VK1S68C资料 SSO24小体积封装,FAE技术支持

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK1S68C 封装形式&#xff1a;SSOP24 概述&#xff1a; VK1S68C是一种带键盘扫描接口的数码管或点阵LED驱动控制专用芯片&#xff0c;内部集成有3线串行接口、数据锁存器、LED 驱动、键盘扫描等电路。SEG脚接LED阳极…

Go 项目(一)

目录基础环境包管理编码规范命名规范注释import 规范错误处理RPC内置 RPC改协议改调用基础 基础部分参考这个系列接下来的这部分是对上面的更新和重构&#xff0c;更加深入理解框架部分 环境 基础环境&#xff0c;主要在Linux上搞&#xff1b;最主要是 docker&#xff0c;do…

Mac 可以玩游戏吗,有哪些游戏可以玩?

Mac 可以玩游戏吗&#xff0c;有哪些游戏可以玩&#xff1f; 新款的 MacBook Pro 入手有一段时间了&#xff0c;期间一直在熟悉 MacOS 系统及日常工作使用&#xff0c;一直都听说 MacBook 是工作本&#xff0c;不得不说工作使用确实很强&#xff0c;但用的久了就还是特别想折腾…

flex 布局:实现一行固定个数,超出强制换行(流式布局)

一、flex 布局基础知识 flex 布局的知识想必不用多说&#xff0c;一些常用的属性如下&#xff1a; 设置在父容器上的属性&#xff1a;display&#xff1a;flex&#xff0c; align-items, justify-content, flex-wrap。 设置在子容器上的属性&#xff0c;通过 flex: 1&#x…

最终一致分布式事务方案解析

业来主流的分布式事务的解决方案主要归位两大类&#xff1a;强一致性分布式事务和最终一致性分布式事务&#xff0c;本文不对强一致性分布式事务做过多描述&#xff0c;主要针对最终一致性方案解析。 根据笔者的工作经验来看&#xff0c;最终一致性方案适用用大部分互联网场景…

SpringBoot 2.7.8 自定义 Starter 自动配置

文章目录SpringBoot 2.7.8 自定义 Starter前言本次练习的代码仓库代码简要说明custom-springboot-starter-demo 的pom文件customer-starter 的pom文件test 的pom文件配置类配置信息SpringBoot 2.7.8 自定义 Starter 前言 前段时间&#xff0c;SpringBoot 出 3.x 版本了。听说…

如何与他人交流 (如何跟老板提涨工资) 第16章

最重要的事情 ---强有力的论证上期我们说根据场景来优化策略,是在隔靴搔痒,然而一个容易给出理由的人很容易成为演讲的高手.说服别人的理性与感性举个例子&#xff0c;我们如果说服别人买一件商品。采用打广告的形式&#xff0c;往往有两种途径。比如说我们要买一辆车。展示它的…

Power BI瀑布图

瀑布图&#xff08;Waterfall Plot&#xff09;也被称为阶梯图&#xff0c;它出现的历史并不长&#xff0c;最初为麦肯锡所创&#xff0c;因自上而下形似瀑布而得名&#xff0c;面世之后以其展示效果清晰而流畅被广为接受&#xff0c;经常在经营和财务分析中使用。 瀑布图是根…

4d view软件 .vol .4dv转 dcom文件

一、 .vol转 dcom文件 1、4d view软件打开vol文件 2、settings--dicom configuration-add&#xff0c;设置如下&#xff08;前面的alias、ae title等设的可以随便一些&#xff0c;我都设了1&#xff09;&#xff0c;然后save&exit&#xff08;第6步设置也可以&#xff09…

Vue13-计算属性computed

首先使用methods方法实现属性计算 步入正题&#xff1a; 计算属性&#xff1a;拿已有的属性计算得出新的属性 1.vue中属性和计算属性是分开的&#xff0c;属性在data中&#xff0c;计算属性在computed中 computed中计算属性以对象的形式存贮 这里是将fullName以及get的返回值…

计算机网络基础学习指南(一)

前言 计算机网络基础是研发/运维工程师都需掌握的知识&#xff0c;但往往会被忽略。 今天&#xff0c;我将献上一份详细 & 清晰的计算机网络基础学习指南&#xff0c;涵盖 TCP / UDP协议、Http协议、Socket等&#xff0c;希望你们会喜欢。 1. 计算机网络体系结构 1.1 简…

深入理解ThreadLocal看这篇就够了-应用场景、内部原理、内存泄漏以及父子线程如何共享数据

为了帮助大家在项目中更好使用ThreadLocal&#xff0c;本文向大家介绍ThreadLocal原理和常见问题&#xff0c;具体内容如下&#xff1a;ThreadLocal是什么ThreadLocal的应用场景ThreadLocal的内部原理ThreadLocal内存泄露问题父子线程如何共享数据ThreadLocal是什么java.lang.T…

CCS10新建TMS320F28335工程

CCS10新建TMS320F28335工程 1. 新建工程 点击Project → New CCS Project。选择芯片类型(TMS320F28335)、仿真器类型(XDS200V3)、新建工程名称、选择新建一个空工程。 2. 配置工程选项 右键项目工程名&#xff0c;进入配置选项Proprrties。或者AltEnter打开配置选项。在工程…