数据结构之线性表(3)

news2024/11/26 18:20:07

数据结构之线性表(3)

上文我们了解了线性表的静动态存储的相关操作,此篇我们对线性表中链表的相关操作探讨。
在进行链表的相关操作时,我们先来理解单链表是什么?

1.链表的概念及结构

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
在这里插入图片描述

//单链表的结点定义
struct SeqListNode
{
	datatype data;
	struct SeqListNode * next;
};
typedef struct SeqListNode SLNode;

在这里插入图片描述

单链表的基本操作:

1.头插

//头插
void SLNpushfront(SLNode** pphead,datatype x)
{
	//1.不存在其他结点
	if (*pphead == NULL)
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		*pphead = newnode;
	}
	else
	{
		//2.存在其他结点
		SLNode* tmp = (SLNode*)malloc(sizeof(SLNode));
		tmp->data = x;
		tmp->next = *pphead;
		*pphead = tmp;
	}
}

2.尾插

//尾插
void SLNpushback(SLNode** pphead, datatype x)
{
	//1.不存在其他结点
	if (*pphead == NULL)
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		*pphead = newnode;
	}
	else
	{
		//2.存在其他结点
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		tail->next = newnode;
		newnode->data = x;
		newnode->next = NULL;
	}
}

3.头删

//头删
void SLNpopfront(SLNode** pphead)
{
	//1.链表中0个结点,无法删除
	if (*pphead == NULL)
	{
		printf("链表中没有结点,无法删除\n");
		exit(-1);
	}
	//2.链表中只有一个结点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		(*pphead) = NULL;
	}
	//3.链表中有一个以上结点
	SLNode* tmp = (*pphead)->next;
	free(*pphead);
	(*pphead) = NULL;
	*pphead = tmp;
}

4.尾删

//尾删
void SLNpopback(SLNode** pphead)
{
	//1.链表中0个结点
	if (*pphead ==NULL)
	{
		printf("链表中没有结点,无法删除\n");
		exit(-1);
	}
	//2.链表中只有一个结点,就类似于只有一个结点的头删
	if ((*pphead)->next ==NULL)
	{
		free(*pphead);
		(*pphead) = NULL;
	}
	//3.链表中有一个以上结点
	SLNode* prev = NULL;
	SLNode* tail = (*pphead);
	while (tail->next != NULL)
	{
		prev = tail;
		tail = tail->next;
	}
	free(tail);
	tail = NULL;
	prev->next = NULL;
}

5.打印

//打印
void SLNprintf(SLNode* pphead)
{
	while (pphead)
	{
		printf("%d ", pphead->data);
		pphead = pphead->next;
	}
}

6.查找

//查找
SLNode* SLNfind(SLNode* phead, datatype x)
{
	SLNode* cur = phead;
	while (cur != NULL)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

7.指定位置插入

//指定位置插入
void SLNinsert(SLNode** pphead, SLNode* pos, datatype x)
{
	if (pos == *pphead)
	{
		SLNpushfront(pphead, x);//若pos==*pphead,就等同于头插
	}
	else
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = newnode;
		newnode->next = pos;
	}
}

7.指定位置删除

void SLNdeleate(SLNode** pphead, SLNode* pos)
{
	if (pos == *pphead)
	{
		SLNpopfront(pphead);//若pos==*pphead,就等同于头删
	}
	else
	{
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}

完整代码如下:

#include<stdio.h>
#include<stdlib.h>
typedef int datatype;
//单链表结点的定义
struct SeqListNode
{
	datatype data;
	struct SLNode* next;
};
typedef struct SeqListNode SLNode;
//头插
void SLNpushfront(SLNode** pphead,datatype x)
{
	//1.不存在其他结点
	if (*pphead == NULL)
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		*pphead = newnode;
	}
	else
	{
		//2.存在其他结点
		SLNode* tmp = (SLNode*)malloc(sizeof(SLNode));
		tmp->data = x;
		tmp->next = *pphead;
		*pphead = tmp;
	}
}
//尾插
void SLNpushback(SLNode** pphead, datatype x)
{
	//1.不存在其他结点
	if (*pphead == NULL)
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		*pphead = newnode;
	}
	else
	{
		//2.存在其他结点
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		tail->next = newnode;
		newnode->data = x;
		newnode->next = NULL;
	}
}
//头删
void SLNpopfront(SLNode** pphead)
{
	//1.0个结点,无法删除
	if (*pphead == NULL)
	{
		printf("链表中没有结点,无法删除\n");
		exit(-1);
	}
	//2.链表中只有一个结点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		(*pphead) = NULL;
	}
	//3.链表中有一个以上结点
	SLNode* tmp = (*pphead)->next;
	free(*pphead);
	(*pphead) = NULL;
	*pphead = tmp;
}
//尾删
void SLNpopback(SLNode** pphead)
{
	//1.链表中0个结点
	if (*pphead ==NULL)
	{
		printf("链表中没有结点,无法删除\n");
		exit(-1);
	}
	//2.链表中只有一个结点,就类似于只有一个结点的头删
	if ((*pphead)->next ==NULL)
	{
		free(*pphead);
		(*pphead) = NULL;
	}
	//3.链表中有一个以上结点
	SLNode* prev = NULL;
	SLNode* tail = (*pphead);
	while (tail->next != NULL)
	{
		prev = tail;
		tail = tail->next;
	}
	free(tail);
	tail = NULL;
	prev->next = NULL;
}
//打印
void SLNprintf(SLNode* pphead)
{
	while (pphead)
	{
		printf("%d ", pphead->data);
		pphead = pphead->next;
	}
}
//指定位置插入
void SLNinsert(SLNode** pphead, SLNode* pos, datatype x)
{
	if (pos == *pphead)
	{
		SLNpushfront(pphead, x);
	}
	else
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = newnode;
		newnode->next = pos;
	}
}
//指定位置删除
void SLNdeleate(SLNode** pphead, SLNode* pos)
{
	if (pos == *pphead)
	{
		SLNpopfront(pphead);
	}
	else
	{
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}
//查找
SLNode* SLNfind(SLNode* phead, datatype x)
{
	SLNode* cur = phead;
	while (cur != NULL)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
int main()
{
	SLNode* plist = NULL;
	SLNpushfront(&plist, 1);
	SLNpushfront(&plist, 2);
	SLNpushfront(&plist, 3);
	SLNpushback(&plist, 4);
	SLNpushback(&plist, 5);
	SLNpushback(&plist, 6);
	SLNpushback(&plist, 7);
	SLNpopfront(&plist);
	SLNpopback(&plist);
	SLNprintf(plist);
	return 0;
}

以上就是单链表中最简单的一种结构的相关操作啦,谢谢大家支持。
在这里插入图片描述

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

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

相关文章

密钥管理简介

首先我们要知道什么是密钥管理&#xff1f; 密钥管理是一种涉及生成、存储、使用和更新密钥的过程。 密钥的种类 我们知道&#xff0c;对称密码主要包括分组密码和序列密码。但有时也可以将杂凑函数和消息认证码划分为这一类&#xff0c;将它们的密钥称为对称密钥&#xff1b;…

RAG与Langchain简介

RAG与Langchain简介 什么是RAGRAG解决的问题RAG工作流程RAG调优策略LangChain简介 什么是RAG 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff09;&#xff0c;主要是通过从外部给大模型补充一些知识&#xff0c;相当于给模型外挂了一个知识库&#xff0c;让…

Navicat 安装及初步配置指南

Navicat 是一款广泛使用的数据库管理工具&#xff0c;支持多种数据库&#xff0c;如 MySQL、PostgreSQL、SQLite 等。以下是 Navicat 安装步骤的详细说明&#xff1a; 在 Windows 上安装 Navicat 下载 Navicat 安装包&#xff1a; 访问 Navicat 官方网站&#xff1a;Navicat 官…

iCopy for Mac 剪切板 粘贴工具 历史记录 安装(保姆级教程,新手小白轻松上手)

Mac分享吧 文章目录 效果可留存文本、图片、文件等复制历史记录也可根据关键字进行历史记录检索点击一下&#xff0c;可复制双击两下&#xff0c;复制内容&#xff0c;并将信息粘贴至鼠标指针处 一、准备工作二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹…

【Vue】Pinia管理用户数据

Pinia管理用户数据 基本思想&#xff1a;Pinia负责用户数据相关的state和action&#xff0c;组件中只负责触发action函数并传递参数 步骤1&#xff1a;创建userStore 1-创建store/userStore.js import { loginAPI } from /apis/user export const useUserStore defineStore(…

Havoc工具

Team端 客户端 打开后需要生成监听器和agent 监听 生成payload 最后上线 HTTPS流量 HTTP流量 心跳

基于微信小程序的在线答题小程序设计与实现

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

安装 Nuxt.js 的步骤和注意事项

title: 安装 Nuxt.js 的步骤和注意事项 date: 2024/6/17 updated: 2024/6/17 author: cmdragon excerpt: Nuxt.js在Vue.js基础上提供的服务器端渲染框架优势&#xff0c;包括提高开发效率、代码维护性和应用性能。指南详细说明了从环境准备、Nuxt.js安装配置到进阶部署技巧&…

大模型KV Cache节省神器MLA学习笔记(包含推理时的矩阵吸收分析)

首先&#xff0c;本文回顾了MHA的计算方式以及KV Cache的原理&#xff0c;然后深入到了DeepSeek V2的MLA的原理介绍&#xff0c;同时对MLA节省的KV Cache比例做了详细的计算解读。接着&#xff0c;带着对原理的理解理清了HuggingFace MLA的全部实现&#xff0c;每行代码都去对应…

dentacare - hackmyvm

简介 靶机名称&#xff1a;dentacare 难度&#xff1a;中等 靶场地址&#xff1a;https://hackmyvm.eu/machines/machine.php?vmdentacare 本地环境 虚拟机&#xff1a;vitual box 靶场IP&#xff08;dentacare&#xff09;&#xff1a;192.168.56.120 跳板机IP(window…

使用Multipass编译OpenHarmony工程

Multipass 是一个轻量级虚拟机管理器&#xff0c;支持 Linux、Windows 与 macOS&#xff0c;这是为希望使用单个命令提供全新 Ubuntu 环境的开发人员而设计的。使用 Linux 上的 KVM、Windows 上的 Hyper-V 和 macOS 上的 HyperKit 来以最小的开销运行 VM&#xff0c;同时它还可…

驱动开发(二):创建字符设备驱动

往期文章&#xff1a; 驱动开发&#xff08;一&#xff09;&#xff1a;驱动代码的基本框架 驱动开发&#xff08;二&#xff09;&#xff1a;创建字符设备驱动 ←本文 驱动开发&#xff08;三&#xff09;&#xff1a;内核层控制硬件层 目录 字符驱动设备的作用 函数 …

找不到vcomp100.dll无法继续执行代码的原因及解决方法

在日常使用电脑的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“vcomp100.dll丢失”。那么&#xff0c;vcomp100.dll是什么&#xff1f;它为什么会丢失&#xff1f;对电脑有什么具体影响&#xff1f;如何解决这个问题&#xff1f;本文将为您详细解答…

SpringBoot整合SpringDataRedis

目录 1.导入Maven坐标 2.配置相关的数据源 3.编写配置类 4.通过RedisTemplate对象操作Redis SpringBoot整合Redis有很多种&#xff0c;这里使用的是Spring Data Redis。接下来就springboot整合springDataRedis步骤做一个详细介绍。 1.导入Maven坐标 首先&#xff0c;需要导…

dp练习2

如何分析这个题目呢&#xff0c;要想着当前的最优解只和前面的最优解有关 class Solution { public:int numSquares(int n) {vector<int> f(n 1);for (int i 1; i < n; i) {int minn INT_MAX;for (int j 1; j * j < i; j) {minn min(minn, f[i - j * j]);}f[…

基于Java+Swing贪吃蛇小游戏(含课程报告)

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

“Redis中的持久化:深入理解RDB与AOF机制“

目录 # 概念 1. RDB持久化 1.1 备份是如何执行的&#xff08;RDB过程&#xff09; 1.2 配置文件信息 1.3 RDB持久化操作 1.4 RDB优势 1.5 RDB劣势 1.6 RDB做备份 2. AOF持久化 2.1 AOF开启及使用 2.2 异常恢复 2.3 配置文件操作 2.4 AOF持久化流程 2.5 优点 2.6…

基于振弦采集仪的地下综合管廊工程安全监测技术研究

基于振弦采集仪的地下综合管廊工程安全监测技术研究 地下综合管廊工程是一项重要的城市基础设施工程&#xff0c;承载着城市供水、供电、供热、排水等重要功能。为了确保地下综合管廊工程的安全运行&#xff0c;需要进行有效的安全监测。本文将重点研究基于振弦采集仪的地下综…

Python学习笔记12:进阶篇(一),类的相关知识

前言 在讲类之前&#xff0c;我们简单介绍一些Python的知识。这些知识在入门篇没讲&#xff0c;想学Python的&#xff0c;基本都对Python有基础的了解&#xff0c;但是今天开始的进阶知识&#xff0c;会涉及到一些Python的特性&#xff0c;所以在这里介绍一下。 Python是一种高…

vivado NODE、PACKAGE_PIN

节点是Xilinx部件上用于路由连接或网络的设备对象。它是一个 WIRE集合&#xff0c;跨越多个瓦片&#xff0c;物理和电气 连接在一起。节点可以连接到单个SITE_&#xff0c; 而是简单地将NETs携带进、携带出或携带穿过站点。节点可以连接到 任何数量的PIP&#xff0c;并且也可以…