【数据结构】链表(C语言实现)

news2025/6/20 13:03:43

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c语言系列专栏:c语言之路重点知识整合 🔥
给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

在经过数组基本知识的学习后,我们知道数组可以用来存放一组数据

但是数组的个数是固定的,如果我们想动态改变这组数据,通过数组就十分麻烦

基于结构体的知识基础上,本文将介绍一种新的数据结构——链表


链表 目录

  • 链表的基本概念
    • 步骤:
  • 添加:
  • 插入:
  • 删除:
    • 1.按下标删除
    • 2.按数据删除
  • 查找
    • 1.按下标查找返回数据
    • 2.按数据查找返回下标

链表的基本概念

根据数组长度固定的特点,我们可以将数组比作货车,货车装满了数据,添加数据只能再装一辆货车(定义一个新数组),修改数据还要删除某些已有数据,太具有局限性。

从长度固定的角度出发,我们需要一个不是长度固定,还能存放一组数据的“数据类型”,就是链表

如果说数组是货车,那链表就是火车,它可以随意地在一组数据的末端添加新数据,还可以在中间添加删除等,非常灵活,那么链表是如何定义的呢?

链表通过结构体指针实现。通常需要定义一个表示链表节点的结构体,包含两个成员:数据指向下一个节点的指针

一个链表节点的结构体定义例如:

定义节点时同时定义节点的指针,在后续堆区创建、链表遍历等都会用到
typedef struct node			//使用typedef简化命名
{
	int data;	//数据
	struct node* next;//下一个节点的 结构体指针
} Node,* P_NODE,*PNode;	//节点指针

一个链表是由多个结点连接组成,链表中的第一个节点称为头节点,最后一个节点称为尾节点

头节点通常用一个指针来保存,指向链表的第一个节点。如果链表为空,则头指针为NULL

在定义好节点的结构体后,创建一个(静态)链表的过程为:

步骤:

1.声明一个头节点,一般头节点不存贮数据

	Node header = { -1,NULL };

2.创建几个节点变量: 栈区 或 堆区

	Node n1 = { 0,NULL };
	Node n2 = { 6,NULL };
	Node n3 = { 2,NULL };
	Node n4 = { 2,NULL };

	P_NODE newNode = malloc(sizeof(Node));	//记得free

(堆区知识:堆区详解)

  1. 链接所有节点
	header.next= &n1;
	n1.next = &n2;
	n2.next = &n3;
	n3.next = &n4;
	n4.next = newNode;	//已经是结构体指针类型,不需要再取地址
	newNode->next = NULL;
  1. 遍历链表
//Node* p;
	P_NODE p= header.next;
	while (p!=NULL)
	{
		printf("%d ", p->data);
		p=p->next;
	}
	
	free(newNode);

在这里插入图片描述

添加:

我们可以将添加节点封装为函数:

PNode create(int data)
{
	PNode newNode = (PNode)malloc(sizeof(NODE));
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}

在链表上添加数据,定义一个add函数,分为一开始链表为空和不为空两种情况

void add(PNode node)
{
	if (header == NULL)
	{
		header = ender = node;
	}
	else
	{
		ender->next = node;
		ender=node;
	}
	
}

然后先调用create函数创建节点,再使用add添加到链表: add(create(添加的数据));
在这里插入图片描述

插入:

理想的在后面插入数据

void insert_behind(int index, PNode node)
{
	PNode p = header;
	for (int i = 0; i < index; i++)
	{
		p = p->next;
	}
	//保留p的下一个
	PNode q = p->next;
	node->next = q;
	p->next = node;
}

然后先调用create创建插入的节点,通过插入的下标插入到链表中:
在这里插入图片描述

删除:

1.按下标删除

现只考虑理想的中间删除,不考虑删头删尾:

void remove_index(int index)
{
	PNode p = header;
	PNode q;
	for (int i = 0; i < index; i++)
	{
		q = p;
		p = p->next;
	}

	PNode m = p->next;

	q->next = m;
	free(p);
}

在这里插入图片描述

2.按数据删除

void remove_data(int data)
{
	PNode p = header;
	PNode q;
	while (p->data != data)
	{
		q = p;
		p = p->next;
	}
	PNode m = p->next;
	q->next = m;
	free(p);

}

在这里插入图片描述

查找

先写一个得到链表长度的函数:

int size()
{
	PNode p = header;
	int i=0;
	while (p!=NULL)
	{
		i++;
		p = p->next;
	}
	return i;
}

在这里插入图片描述

1.按下标查找返回数据

int get(int index)
{
	PNode p = header;
	for (int i = 0; i < index; i++)
	{
		p = p->next;
	}
	return p->data;
}

在这里插入图片描述

2.按数据查找返回下标

int indexOf(int data)
{
	int index=0;
	PNode p = header;
	while (p->data != data)
	{
		index++;
		p = p->next;
	}
	return index;
}

在这里插入图片描述


本文全部代码(供自己调试查看):

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

typedef struct node
{
	int data;				//数据
	struct node *next;		//结构体指针
}NODE,*PNode;

PNode create(int data);
void add(PNode node);

void insert_behind(int index, PNode node);

void remove_index(int index);
void remove_data(int data);

int size();
int get(int index);
int indexOf(int data);


PNode header = NULL;	//头尾结点的位置
PNode ender = NULL;

int main()
{
	add(create(1));
	add(create(2));
	add(create(3));
	add(create(4));
	insert_behind(2, create(9));
	//remove_index(1);
	remove_data(9);
	printf("%d\n", indexOf(4));
	return 0;
}

PNode create(int data)
{
	PNode newNode = (PNode)malloc(sizeof(NODE));
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}

void add(PNode node)
{
	if (header == NULL)
	{
		header = ender = node;
	}
	else
	{
		ender->next = node;
		ender=node;
	}
	
}

/*理想的在后面插入数据*/
void insert_behind(int index, PNode node)
{
	PNode p = header;
	for (int i = 0; i < index; i++)
	{
		p = p->next;
	}
	//保留p的下一个
	PNode q = p->next;
	node->next = q;
	p->next = node;
}

void remove_index(int index)
{
	PNode p = header;
	PNode q;
	for (int i = 0; i < index; i++)
	{
		q = p;
		p = p->next;
	}

	PNode m = p->next;

	q->next = m;
	free(p);
}

void remove_data(int data)
{
	PNode p = header;
	PNode q;
	while (p->data != data)
	{
		q = p;
		p = p->next;
	}
	PNode m = p->next;
	q->next = m;
	free(p);
	
}

int size()
{
	PNode p = header;
	int i=0;
	while (p!=NULL)
	{
		i++;
		p = p->next;
	}
	return i;
}

int get(int index)
{
	PNode p = header;
	for (int i = 0; i < index; i++)
	{
		p = p->next;
	}
	return p->data;
}

int indexOf(int data)
{
	int index=0;
	PNode p = header;
	while (p->data != data)
	{
		index++;
		p = p->next;
	}
	return index;
}

至此,对于一个静态链表的增删改查就结束了

后面我会总结出关于链表的常用函数 组件化封装


在这里插入图片描述

大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)

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

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

相关文章

丁鹿学堂:vue的脚手架项目基础入门和单文件代码分析

在实际开发中&#xff0c;我们都是通过脚手架创建vue项目的。 默认安装了node&#xff0c;yarn&#xff0c; 1创建项目&#xff1a; yarn create vue为了学习&#xff0c;我们选择最简单的培训&#xff0c;一路下来都选no 2 创建项目以后&#xff0c;只是搭起了架子&#x…

Uniapp一言“一句话接口调用

界面 代码 <template><view ><view class"uni-padding-wrap uni-common-mt"><view class"text-box" scroll-y"true"><text>{{data}}</text></view><view class"uni-btn-v"><butto…

(C语言版)力扣(LeetCode)栈和队列面试题

栈和队列面试题 20. 有效的括号题目解法一&#xff1a;建立栈解决解法二&#xff1a;数组模拟栈解决 225. 用队列实现栈题目解法&#xff1a;两个队列实现栈 232. 用栈实现队列题目解法&#xff1a;两个栈实现队列 622. 设计循环队列题目解法一&#xff1a;数组解法二&#xff…

AcWing算法提高课-1.3.3宠物小精灵之收服

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事。 一天&#xff0c;小智和皮卡丘来到了小精灵狩猎场&#xff0c;里面有…

Stable Diffusion 生成高清图片

Stable Diffusion 生成 8K 高清图片 0. 简介1. 安装 ultimate-upscale-for-automatic1111 插件2. 安装 4x-UltraSharp 模型3. 生成 1 张普通图片4. 生成 1 张高清图片 0. 简介 记录一下使用 Stable Diffusion 生成高清图片使用的插件和过程。 1. 安装 ultimate-upscale-for-a…

Qt推流程序(视频文件/视频流/摄像头/桌面转成流媒体rtmp+hls+webrtc)可在网页和播放器远程观看

一、前言说明 推流直播就是把采集阶段封包好的内容传输到服务器的过程。其实就是将现场的视频信号从手机端&#xff0c;电脑端&#xff0c;摄影机端打包传到服务器的过程。“推流”对网络要求比较高&#xff0c;如果网络不稳定&#xff0c;直播效果就会很差&#xff0c;观众观…

Linux基础篇-将虚拟机的网络配置成静态的

一般都是主机连接服务器&#xff0c;服务器连接主机也是为了上网&#xff0c;通过NAT地址转换就可以。为了防止服务器的IP地址变化&#xff0c;将虚拟机的IP地址设置成静态的。 NAT模式下&#xff0c;为了让主机和虚拟机之间能互相ping通&#xff0c;主机虚拟了一张网卡出来&am…

PicGo+阿里云OSS+Typora图床设置实践及解决方案

你是否遇到想跨平台看markdown文件结果图片加载不出&#xff0c;csdn上传的时候还要手动操作的命苦感&#xff0c;那就接着往下看吧&#xff01; 本文为作者在安装过程中的总结&#xff0c;争取以最简洁的方式帮助大家安装 markdown语法在程序员的生活中运用广泛&#xff0c;…

测试用例、测试流程模型、测试方法详解 超详细分解

1. 测试用例 1.1 测试用例前提 什么是测试用例&#xff1f; 一组由前提条件、测试输入、执行条件以及预期结果等组成&#xff0c;以完成对某个特定需求或者目标测试的数据&#xff0c;体现测试方案、方法、技术和策略的文档。 为什么编写测试用例 &#xff08;1&#xff0…

股票量价关系基础知识1

什么叫成交量 成交量的概念中&#xff0c;包含“成交”、“成交量”和“成交值”三个子概念。 所谓“成交”&#xff0c;就是买卖双方同意所达成的交易行为。“成交”是商业用语&#xff0c;因为股市本事就是一项商业活动&#xff0c;股票市场就是一个大商场&#xff0c;各地证…

每日学术速递5.9

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Tracking through Containers and Occluders in the Wild(CVPR 2023) 标题&#xff1a;在野外通过容器和遮挡物进行追踪 作者&#xff1a;Basile Van Hoorick, Pavel Tokmakov, Si…

C++数据封装以及定义结构的详细讲解鸭~

名字&#xff1a;阿玥的小东东 博客主页&#xff1a;阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 定义结构 访问结构成员 结构作为函数参数 指向结构的指针 typedef 关键字 C 数据封装 数据封装的实例 设计策略 C 类 &…

UEngine运行器2.1.0——优化UEngine安装器(Ubuntu)、修复问题

介绍 新版本Deepin/UOS发布后&#xff0c;可以在应用商店安装部分官方已适配的安卓应用&#xff0c;对爱好者来说&#xff0c;不能自己安装APK软件包始终差点意思&#xff0c;本程序可以为Deepin/UOS上的UEngine安卓运行环境安装自定义APK软件包&#xff0c;并能发送安装的APK包…

【GAMES101】作业1学习总结

本系列博客为记录笔者在学习GAMES101课程时遇到的问题与思考。 GAMES101&#xff1a;课程官网GAMES101&#xff1a;B站视频GAMES101&#xff1a;相关文件下载(百度网盘) 一、基础题 通过Assignment1.pdf可以知道基础题的任务就是填充完整两个函数 get_model_matrix()get_pro…

详解c++---array和模板

目录标题 什么是array非类型模板参数函数模板的特化为什么会有特化如何进行特化类模板的特化部分特化模板特化参数的限制 模板的匹配规则模板的分离编译模板的总结 什么是array 在c语言里面使用一个括号就能申请到一段连续的空间&#xff0c;比如说想要申请一段空间用于存储10…

每日学术速递5.8

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Personalize Segment Anything Model with One Shot 标题&#xff1a;一键个性化细分任何模型 作者&#xff1a;Renrui Zhang, Zhengkai Jiang, Ziyu Guo, Shilin Yan, Junting Pa…

ArcMap创建格网统计图

目录 前言 一、人口数据获取 来源一&#xff1a;中科院地理所公开数据集 来源二&#xff1a;WorldPop数据集 二、人口格网统计步骤 1.创建渔网 2.人口数据处理 2.1 栅格转点 2.2 空间插值——处理人口缺失数据 2.3 空间连接——渔网人口统计 总结 前言 在科研中&am…

南华大学编译原理----词法分析器的设计与实现、语法分析器的设计与实现

下载链接&#xff1a;&#xff08;各位同学不需要充钱哈&#xff0c;这种我也没有收益&#xff0c;去淘宝上面找个代下&#xff0c;大概0.5元就能下载实验报告&#xff0c;用来给同学们参考&#xff0c;下载积分不是我设置的&#xff0c;是网站自己默认的&#xff09; --------…

English Learning - L3 作业打卡 Lesson1 Day1 2023.5.5 周五

English Learning - L3 作业打卡 Lesson1 Day1 2023.5.5 周五 引言&#x1f349;句1: Every people has its own way of saying things , its own special expressions.成分划分弱读连读语调自身问题&#xff1a; &#x1f349;句2: Many everyday American expressions are ba…

股票量价关系基础知识6----图解各阶段量价关系:价涨量平

图解各阶段量价关系&#xff1a;价涨量平 价涨量平是指股价上涨而成交量却变化不大&#xff0c;这可能是场外资金仍在观望&#xff0c;进场做多力量不大。 一、上涨初期的价涨量平 &#xff08;一&#xff09;形态分析 股价触底反弹后小幅上涨&#xff0c;成交量却持平&#x…