数据结构之单链表的基本操作

news2025/1/18 3:27:09

目录

一.定义一个单链表

二.实现基本操作 

1)链表的打印

2)链表的尾插 

3)链表的头插

4)链表的尾删

5)链表的头删

6) 链表的查找

7)在指定位置之前插入数据

8)在指定位置之后插入数据

9)删除pos节点

10)删除pos之后的节点

11)销毁链表


搭配食用更佳哦~~

 数据结构之单单单——链表-CSDN博客

一.定义一个单链表

创建一个头文件 SList.h,进行准备工作

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//定义节点的结构
//数据 + 指向下一个节点的指针
typedef int SLTDataType;

typedef struct SListNode {
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

添加上要实现的方法:

//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);
//尾删
void SLTPopBack(SLTNode** pphead);
//头删
void SLTPopFront(SLTNode** pphead);

//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);

//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);

//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos);
//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos);

//销毁链表
void SListDesTroy(SLTNode** pphead);

二.实现基本操作 

创建一个 SList.c 文件

1)链表的打印

      我们首先需要创建四个节点,但此时这四个节点是孤立的,既然是链表我们还需要给它们链接上,所以我们接下来创建指针 将这四个节点链接起来,注意最后一个指针指向的应是空NULL,做好准备工作之后我们来调用链表的打印:

#include"SList.h"

void SListTest01()
{
	//链表是由一个一个的节点组成
	//创建几个节点
	SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
	node1->data = 1;

	SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
	node2->data = 2;

	SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
	node3->data = 3;

	SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
	node4->data = 4;

	//将四个节点连接起来
	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = NULL;

	//调用链表的打印
	SLTNode* plist = node1;
	SLTPrint(plist);
}

 然后在另一个 test.c 文件调用它来打印链表:

#include"SList.h"
void SLTPrint(SLTNode* phead)
{
	SLTNode* pcur = phead;
	while (pcur)//pcur != NULL
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("NULL\n");
}

于是我们从运行结果就可以清晰的看到链表是如何遍历的:

 

2)链表的尾插 

//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	//*pphead 就是指向第一个节点的指针
	//空链表和非空链表
	SLTNode* newnode = SLTBuyNode(x);
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		//找尾
		SLTNode* ptail = *pphead;
		while (ptail->next)
		{
			ptail = ptail->next;
		}
		//ptail指向的就是尾结点
		ptail->next = newnode;
	}
}

3)链表的头插

//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = SLTBuyNode(x);
	//newnode *pphead
	newnode->next = *pphead;
	*pphead = newnode;
}

4)链表的尾删

//尾删
void SLTPopBack(SLTNode** pphead)
{
	//链表不能为空
	assert(pphead && *pphead);
	//链表只有一个节点
	if ((*pphead)->next == NULL) //-> 优先级高于*
	{
		free(*pphead);
		*pphead = NULL;
	}
	else {
		//链表有多个节点

		SLTNode* prev = *pphead;
		SLTNode* ptail = *pphead;
		while (ptail->next)
		{
			prev = ptail;
			ptail = ptail->next;
		}
		//prev ptail
		free(ptail);
		ptail = NULL;
		prev->next = NULL;
	}
}

5)链表的头删

//头删
void SLTPopFront(SLTNode** pphead)
{
	//链表不能为空
	assert(pphead && *pphead);

	SLTNode* next = (*pphead)->next; //-> 优先级高于*
	free(*pphead);
	*pphead = next;
}

6) 链表的查找

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

7)在指定位置之前插入数据

//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pphead && *pphead);
	assert(pos);
	SLTNode* newnode = SLTBuyNode(x);
	//若pos == *pphead;说明是头插
	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
	}
	else {
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		//prev -> newnode -> pos
		newnode->next = pos;
		prev->next = newnode;
	}
}

8)在指定位置之后插入数据

//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);

	SLTNode* newnode = SLTBuyNode(x);
	//pos -> newnode -> pos->next
	newnode->next = pos->next;
	pos->next = newnode;
}

9)删除pos节点

 

//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead && *pphead);
	assert(pos);
	//pos是头结点/pos不是头结点
	if (pos == *pphead)
	{
		//头删
		SLTPopFront(pphead);
	}
	else {
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		//prev pos pos->next
		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}
}

10)删除pos之后的节点

//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos)
{
	assert(pos && pos->next);
	SLTNode* del = pos->next;
	//pos del del->next
	pos->next = del->next;
	free(del);
	del = NULL;
}

11)销毁链表

//销毁链表
void SListDesTroy(SLTNode** pphead)
{
	assert(pphead && *pphead);

	SLTNode* pcur = *pphead;
	while (pcur)
	{
		SLTNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	//pcur
	*pphead = NULL;
}

     当我们可以使用这些基本操作后,和顺序表一样,我们可以来实现更复杂的操作~~~例如用链表进行通讯录的实现~~

    🎈🎈完结撒花🎈🎈


 

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

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

相关文章

内网安全综合管理系统是什么 | 好用的内网安全管理系统有哪些

内网安全综合管理系统是指一种集成终端管理、网络管理、内容管理、资产管理等功能的综合性安全管理系统。它主要对内网上的主机进行统一安全管理&#xff0c;包括对网络主机用户操作实施监督控制&#xff0c;并对主机中的安全软件&#xff08;如主机入侵监测系统、主机防火墙和…

国内首发 | CSA大中华区启动《AI安全产业图谱(2024)》调研

在人工智能&#xff08;AI&#xff09;技术的快速发展浪潮中&#xff0c;AI安全已成为全球关注的焦点。为应对AI安全带来的挑战&#xff0c;确保AI技术的健康发展&#xff0c;全球范围内的研究机构、企业和技术社区都在积极探索解决方案。 在这一背景下&#xff0c;CSA大中华区…

git 常用命令 git怎么撤销命令 持续更新中!!!!

基本流程 # 拉取仓库 git clone 仓库地址 # 拉取最新版本 git pull # 本地提交 git add . git commit -m "本次提交信息&#xff01;" # 推送上云 git push分支 # 创建分支 git checkout -b cart # 删除本机的分支 git branch -d cart # 切换分支 本地切换到主分支…

将本地托管模型与 Elastic AI Assistant 结合使用的好处

作者&#xff1a;来自 Elastic James Spiteri, Dhrumil Patel 当今公共部门组织利用生成式人工智能解决安全挑战的一种方式。 凭借其筛选大量数据以发现异常模式的能力&#xff0c;生成式人工智能现在在帮助团队保护其组织免受网络威胁方面发挥着关键作用。 它还可以帮助安全专…

LayaAir引擎全面支持淘宝小游戏、小程序、小部件的发布

在最新的3.1版本和2.13版本中&#xff0c;LayaAir引擎已经全面支持了淘宝小游戏、小程序和小部件的开发和发布。这一重大更新&#xff0c;标志着LayaAir引擎与电商巨头阿里巴巴旗下的淘宝平台形成生态合作&#xff0c;在为广大开发者提供更加强大、高效的跨平台开发工具和解决方…

train_gpt2_fp32.cu

源程序 llm.c/test_gpt2_fp32.cu at master karpathy/llm.c (github.com) #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <assert.h> #include <float.h> #include <string.h> #include…

06.命令的组合使用

命令的组合使用 1.查询当前整个系统每个进程的线程数 我们经常遇到这样的问题&#xff0c;比如某台服务器的CPU 使用率飙升&#xff0c;通过top命令查看是某个程序&#xff08;例如java&#xff09;占用的cpu比较大&#xff0c;现在需要查询java各个进程下的线程数情况。可以通…

各种依赖注入和分层解耦

分层解耦 三层架构 controller:控制层&#xff0c;接收前端发送的请求&#xff0c;对请求进行处理&#xff0c;并响应数据 service:业务逻辑层&#xff0c;处理具体业务的逻辑 dao:数据访问&#xff0c;负责数据访问操作&#xff0c;包括数据的增、删、改、查 流程为&…

初阶C语言(8) - 实用的调试技巧

1. 什么是bug? bug 是计算机领域专业术语&#xff0c;是计算机在硬件、软件、协议和系统安全策略上存在的缺陷&#xff0c;攻击者能够在未授权情况下访问的危害&#xff0c;世界最早的一批程序设计师之一&#xff0c;美国的葛丽丝霍波在调试设备时出现故障&#xff0c;拆开继电…

MySQL——变量的定义与使用

新建链接&#xff0c;自带world数据库&#xff0c;里面自带city表格。 DQL # MySQL变量的定义与使用 #1、不允许数字作为开头 #2、只能用_或$符号&#xff0c;不允许使用其他符号 #3、不允许使用关键字或保留字 set userName小可爱; select userName; #标识符只影响当前查询#…

python3.12.0 在Linux 制作镜像包 部署到docker 全过程

项目结构&#xff1a; 比如&#xff0c;在pycharm里需要运行 themain.py 1、上传Linux的目录结构&#xff1a; Dockerfile 文件需要制作&#xff1a; 这里是关键&#xff1a; #基于的基础镜像 FROM python:3.12.0 #代码添加到code文件夹 ADD ./EF_NFCS /code #设置code文…

多客陪玩系统源码APP小程序H5陪玩开发伴游源码游戏陪玩平台源码陪玩平台开发约单源码线下陪玩接单平台app小程序H5源码游戏陪玩app小程序H5开发

出售成品陪玩app小程序H5源码&#xff0c;免费搭建部署和售后服务&#xff0c;并提供源码二开、定制开发等相关服务。 一、陪玩app源码的功能介绍 1、语音聊天: 陪玩app小程序H5源码用户随时创建语音聊天室&#xff0c;实现多用户上麦功能&#xff0c;提高互动聊天体验。 2、游…

说句心里话,别轻易把RFM模型写进简历!

大家好&#xff0c;我是阿粥 我看过很多分析师的简历。 这么多年过去了&#xff0c;简历项目经历里&#xff0c;仍然有不少提到用SQL或者Python进行RFM建模。 项目细节描述各有千秋&#xff0c;但核心逻辑大体绕不开“基于Python对用户数据进行RFM建模&#xff0c;分成x类人群以…

Elasticsearch 索引、类型、文档、分片与副本等核心概念介绍

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《洞察之眼&#xff1a;ELK监控与可视化》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Elasticsearch简介 2、分布式搜索引擎的工作原理…

深入探索数据链路层:网络通信的基石

⭐小白苦学IT的博客主页⭐ ⭐初学者必看&#xff1a;Linux操作系统入门⭐ ⭐代码仓库&#xff1a;Linux代码仓库⭐ ❤关注我一起讨论和学习Linux系统❤ 前言 在网络通信的宏伟世界中&#xff0c;数据链路层扮演着至关重要的角色。它位于物理层和网络层之间&#xff0c;不仅直接…

126.删除链表的倒数第N个节点(力扣)

题目描述 代码解决&#xff08;双指针&#xff09; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, Li…

深入探讨利用大型语言模型的力量的策略 (LLMs)

Note: 提示词工程是一门融合了艺术和科学的学科——它既是对技术的理解&#xff0c;也是对创造力和战略思维的理解。 本文为对LLMS策略分享内容学习后的整理&#xff0c;尝试抛开网上广泛讨论和记录的传统提示词工程技术&#xff0c;展示通过实验学到的新见解&#xff0c;以及…

片冰机工作原理

片冰机工作原理 1、制冰用的水需要加盐(行话叫做加药)至于多少量。看制冰量多少调制泵(柱塞泵)自动调整。 2、制冰机主体分两腔体外腔体内盘的一定密度的铜管。专业术语叫(蒸发腔)就是俗话讲的制冷的东西。 3、外腔体内是一个很规则的圆不锈钢腔体&#xff0c;中心有一三叶刮…

【LAMMPS学习】八、基础知识(6.2)LAMMPS GitHub 教程

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

springcloud服务间调用 feign 的使用

引入依赖包 <!-- 服务调用feign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>创建调用外部服务的接口 需要使用的地方注入 使用 启动类增…