当前位置: 首页 > news >正文

无头单向非循环单链表、带头双向循环链表

文章内容

1. 链表的概念及结构

2. 链表的分类

3.链表实现

4.代码


文章目录

1. 链表的概念及结构

概念:链表是一种物理存储结构非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表
中的指针链接次序实现的 。

 

 现实中 数据结构中

 链表和顺序表的区别

 

2. 链表的分类

实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:

 2.1单向或者双向

 2.2 带头或者不带头

 2.3循环或者非循环

 虽然有这么多的链表的结构,但是我们实际中最常用还是两种结构:

 1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结
构的子结构,如哈希桶图的邻接表等等。另外这种结构在笔试面试中出现很多。


2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都
是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带
来很多优势,实现反而简单了,后面我们代码实现了就知道了。

3.链表实现

3.1无头单向非循环单链表
1.主要功能

 2.接口实现

 

 

 

 

 

 

 

 

 

 

 

 

 以上就是链表每个接口的实现了!!!!

3.2带头双向循环链表
1.主要功能

在理解单链表的基础上,理解带头双向循环链表就简单很多了;

2.接口实现

 

 

 

 

 

 

 

 

 

 

 4.代码

 1.单链表
#pragma once#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLDataType;
typedef struct SListNode
{SLDataType data;struct SListNode* next;
}SLTNode;//打印链表
void SLTPrint(SLTNode* phead);//创建一个新节点
SLTNode* BuySListNode(SLDataType x);//尾插
void SLTPushBack(SLTNode** pphead, SLDataType x);//头插
void SLTPushFront(SLTNode** pphead, SLDataType x);//尾删
void SLTPopBack(SLTNode** pphead);//头删
void SLTPopFront(SLTNode** pphead);//寻找
SLTNode* SLTFind(SLTNode* phead, SLDataType x);// 在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLDataType x);// 在pos以后插入x
void SLTInsertAfter(SLTNode* pos, SLDataType x);// 删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos);// 删除pos的后一个位置
void SLTEraseAfter(SLTNode* pos);//销毁链表
void SLTDestroy(SLTNode** pphead);
#define _CRT_SECURE_NO_WARNINGS 1#include "SList.h"//打印链表
void SLTPrint(SLTNode* phead)
{SLTNode* cur = phead;while (cur){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");
}//创建一个新节点
SLTNode* BuySListNode(SLDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("BuySListNode fail");exit(-1);}newnode->data = x;newnode->next = NULL;return newnode;
}//尾插
void SLTPushBack(SLTNode** pphead, SLDataType x)
{SLTNode* newnode = BuySListNode(x);if (*pphead == NULL){//改变指向结构体的指针,所以要用二级指针*pphead = newnode;}else{SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}//改变结构体,用结构体指针tail->next = newnode;}
}//头插
void SLTPushFront(SLTNode** pphead, SLDataType x)
{SLTNode* newnode = BuySListNode(x);newnode->next = *pphead;*pphead = newnode;}//尾删
void SLTPopBack(SLTNode** pphead)
{//空assert(*pphead);//一个节点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}//一个以上节点SLTNode* tail = *pphead;while (tail->next->next != NULL){tail = tail->next;}free(tail->next);tail->next = NULL;}//头删
void SLTPopFront(SLTNode** pphead)
{//kongassert(*pphead);//非空SLTNode* newnode = (*pphead)->next;free(*pphead);*pphead = newnode;}//寻找
SLTNode* SLTFind(SLTNode* phead, SLDataType x)
{assert(phead);while (phead){if (phead->data == x){return phead;}phead = phead->next;}return NULL;
}// 在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLDataType x)
{assert(pphead);assert(pos);//头插if (*pphead == pos){SLTPushFront(pphead,x);return;}SLTNode* prev = *pphead;SLTNode* newnode = BuySListNode(x);while(prev){if (prev->next == pos){prev->next = newnode;newnode->next = pos;return;}else{prev = prev->next;}}
}// 在pos以后插入x
void SLTInsertAfter(SLTNode* pos, SLDataType x)
{assert(pos);SLTNode* newnode = BuySListNode(x);newnode->next = pos->next;pos->next = newnode;}//SLTNode*  posafter = pos->next;
//pos->next = newnode;
//newnode->next = posafter;// 删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(*pphead);assert(pos);if (*pphead == pos){SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);}}// 删除pos的后一个位置
void SLTEraseAfter(SLTNode* pos)
{assert(pos);//检查尾节点assert(pos->next);SLTNode* del = pos->next;pos->next = pos->next->next;free(del);del = NULL;
}//销毁链表
void SLTDestroy(SLTNode** pphead)
{assert(pphead);SLTNode* cur = *pphead;while (cur){SLTNode* next = cur;next = cur->next;free(cur);cur = next;}*pphead = NULL;
}

 

2.双向链表
#pragma once#include <stdio.h>
#include <assert.h>
#include <stdlib.h>typedef int LTDataTpye;typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataTpye data;}LTNode;//创建新节点
LTNode* BuyLTnode(LTDataTpye x);//初始化
LTNode* LTInit();//打印链表
void LTPrint(LTNode* phead);//头插
void LTPushFront(LTNode* phead, LTDataTpye x);//头删
void LTPopFront(LTNode* phead);//尾插
void LTPushBack(LTNode* phead, LTDataTpye x);//尾删
void LTPopBack(LTNode* phead);//寻找
LTNode* LTFind(LTNode* phead, LTDataTpye x);//在pos之前插入
void LTInsert(LTNode* pos, LTDataTpye x);//消除pos位置的元素
void LTErase(LTNode* pos);//销毁链表
void LTDestroy(LTNode* phead);
#define _CRT_SECURE_NO_WARNINGS 1
#include "DList.h"//创建新节点
LTNode* BuyLTnode(LTDataTpye x)
{LTNode* node = (LTNode *)malloc(sizeof(LTNode));if (node == NULL){perror("BuyLTNode");exit(-1);}node->data = x;node->prev = NULL;node->next= NULL;return node;
}//初始化
LTNode* LTInit()
{LTNode* phead = BuyLTnode(0);phead->next = phead;phead->prev = phead;return phead;
}//打印链表
void LTPrint(LTNode* phead)
{assert(phead);printf("phead<=>");LTNode* cur = phead->next;while (cur!= phead){printf("%d<=>",cur->data);cur = cur->next;}printf("\n");
}//头插
void LTPushFront(LTNode* phead, LTDataTpye x)
{assert(phead);LTNode* newnode = BuyLTnode( x);LTNode* after = phead->next;phead->next = newnode;newnode->prev = phead;newnode->next = after;after->prev = newnode;}//头删
void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* first = phead->next;LTNode* second = first->next;free(first);phead->next = second;second->prev = phead;}//尾插
void LTPushBack(LTNode* phead, LTDataTpye x)
{assert(phead);LTNode* newnode = BuyLTnode(x);LTNode* tail = phead->prev;tail->next = newnode;newnode->prev = tail;newnode->next = phead;phead->prev = newnode;}//尾删
void LTPopBack(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* tail = phead->prev;LTNode* first = tail->prev;free(tail);first->next = phead;phead->prev = first;}//寻找
LTNode* LTFind(LTNode* phead, LTDataTpye x)
{assert(phead);LTNode* cur = phead->next;while (cur !=phead){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}//在pos之前插入
void LTInsert(LTNode* pos, LTDataTpye x)
{assert(pos);LTNode* first = pos->prev;LTNode* newnode = BuyLTnode(x);first->next = newnode;newnode->prev = first;pos->prev = newnode;newnode->next = pos;}//消除pos位置的元素
void LTErase(LTNode* pos)
{assert(pos);LTNode* posprev = pos->prev;LTNode* posafter = pos->next;free(pos);posprev->next = posafter;posafter->prev = posprev;}//销毁链表
void LTDestroy(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != (phead)){LTNode* cur1 = cur;cur = cur->next;free(cur1);}free(phead);phead == NULL;}

相关文章:

无头单向非循环单链表、带头双向循环链表

文章内容 1. 链表的概念及结构 2. 链表的分类 3.链表实现 4.代码 文章目录 1. 链表的概念及结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表 中的指针链接次序实现的 。 现实中 数据结构中 链表和顺序表…...

UE4/5C++多线程插件制作(二十、源码)

目录 头文件 MultiThreadPlugins.uplugin MultiThreadPlugins.Build.cs MultiThreadPlugins.h MTPPlatform.h MTPManage.h RTPAgendy.h MTPThreadTaskManage.h...

构建稳健的PostgreSQL数据库:备份、恢复与灾难恢复策略

在当今数字化时代&#xff0c;数据成为企业最宝贵的资产之一。而数据库是存储、管理和保护这些数据的核心。PostgreSQL&#xff0c;作为一个强大的开源关系型数据库管理系统&#xff0c;被广泛用于各种企业和应用场景。然而&#xff0c;即使使用了最强大的数据库系统&#xff0…...

查看本地mysql账号密码

使用Navicat工具打开本地mysql&#xff0c;新建查询输入下面查询语句 SELECT user, authentication_string FROM mysql.user WHERE userroot将authentication_string 中的加密密码复制出来打开链接&#xff1a; Magic Data 5输入加密的密码&#xff0c;和验证码&#xff0c;点…...

数据结构:顺序表详解

数据结构&#xff1a;顺序表详解 一、 线性表二、 顺序表概念及结构1. 静态顺序表&#xff1a;使用定长数组存储元素。2. 动态顺序表&#xff1a;使用动态开辟的数组存储。三、接口实现1. 创建2. 初始化3. 扩容4. 打印5. 销毁6. 尾插7. 尾删8. 头插9. 头删10. 插入任意位置数据…...

采集数据筛选-过滤不要数据或只保留指定数据

采集文章数据&#xff0c;有时候会遇到一些不需要采集的数据&#xff0c;或者只想采集一些特定的数据&#xff0c;可以使用简数采集器的内容过滤功能&#xff0c;对采集的数据进行筛选&#xff0c;只有符合的数据才采集保留。 可以用于过滤掉一些广告、专题、网站首页等无效数…...

RISC-V基础指令之shift移动指令slli、srli、srai、sll、srl、sra

RISC-V的shift指令是用于对一个寄存器或一个立即数进行位移运算&#xff0c;并将结果存放在另一个寄存器中的指令。位移运算就是把一个操作数的每一位向左或向右移动一定的位数&#xff0c;得到一个新的位。RISC-V的shift指令有以下几种&#xff1a; slli&#xff1a;左逻辑位…...

【沁恒蓝牙mesh】CH58x flash分区与数据存储管理

本文主要介绍了 沁恒蓝牙芯片 CH58x 的flash 分区与数据存储管理 &#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是喜欢记录零碎知识点的小菜鸟。&#x1f60e;&#x1f4dd; 个人主页&#xff1a;欢迎访问我的 Ethernet_Comm 博客主页&…...

Ctfshow web入门 JWT篇 web345-web350 详细题解 全

CTFshow JWT web345 先看题目&#xff0c;提示admin。 抓个包看看看。 好吧我不装了&#xff0c;其实我知道是JWT。直接开做。 在jwt.io转换后&#xff0c;发现不存在第三部分的签证&#xff0c;也就不需要知道密钥。 全称是JSON Web Token。 通俗地说&#xff0c;JWT的本质…...

2023年国家留学基金委(CSC)青年骨干教师项目即将开始申报

国家留学基金委&#xff08;以下简称CSC&#xff09;的青年骨干教师出国研修项目&#xff08;即高校合作项目&#xff09;&#xff0c;将于2023年9月10-25日进行网上报名及申请受理。知识人网小编特提醒申请者注意流程及政策&#xff0c;以防错过申报时间。 青年骨干教师项目&a…...

GC垃圾回收器【入门笔记】

GC&#xff1a;Garbage Collectors 垃圾回收器 C/C&#xff0c;手动回收内存&#xff1b;难调试、门槛高。忘记回收、多次回收等问题 Java、Golang等&#xff0c;有垃圾回收器&#xff1a;自动回收&#xff0c;技术门槛降低 一、如何定位垃圾&#xff1f; https://www.infoq.c…...

在 React 中渲染大型数据集的 3 种方法

随着 Web 应用程序变得越来越复杂&#xff0c;我们需要找到有效的方法来优化性能和渲染大型数据集。在 React 应用程序中处理大型数据集时&#xff0c;一次呈现所有数据可能会导致性能不佳和加载时间变慢。 虚拟化是一种通过一次仅呈现数据集的一部分来解决此问题的技术&#…...

uniapp iOS 消息推送扩展:后台/杀死app进程状态能语音播报

文章目录 引言I 前期准备1.1 配置扩展1.2 测试报文II iOS Extension(扩展)2.1 插件作者配置2.2 插件使用者配置see also引言 HBuilderX3.1.5+版本uni原生插件支持iOS Extension(扩展)。 消息推送离线语音播报插件获取方式: 公z号:iOS逆向: 离线包x10, 源码是x15。 实…...

批量创建可配置物料参数文件

启用可配置物料之后&#xff0c;每次创建新的物料需要通过CU41创建可配置物料&#xff0c;没找大批量创建的程序&#xff0c;所以SHDB录屏搞了一个代码。 前提&#xff1a;物料主数据初始化通过程序导入时&#xff0c;可配置物料参数文件已按照物料代码赋值。 ​效果&#xf…...

性能压力测试的重要性与实施方法

性能压力测试是在软件开发过程中评估系统在不同负载条件下的表现和稳定性的关键步骤。这种测试是为了确定系统在正常和峰值负载下的性能表现&#xff0c;以验证系统是否能够满足用户需求&#xff0c;同时发现潜在的性能问题并加以解决。 首先&#xff0c;性能压力测试对于确保系…...

HCIP入门静态实验

题目及要求 第一步&#xff1a;拓扑的搭建 第二步&#xff1a;路由、IP的配置 r1: <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]sys r1 [r1]int loop [r1]int LoopBack 0 [r1-LoopBack0]ip add 192.168.1.65 27 [r1-LoopBack0]int loop 1 […...

Vue与js的融合,如何编写现代化的前端应用

随着Web应用的不断发展&#xff0c;前端开发已经成为了当今互联网行业中最为流行和重要的领域之一。而在前端开发中&#xff0c;JavaScript无疑是最为常用和基础的语言之一。而Vue.js作为一种轻量级的JavaScript框架&#xff0c;它的出现极大地简化了前端开发的过程&#xff0c…...

Boost开发指南-3.10singleton_pool

singleton_pool singleton_pool与 pool的接口完全一致&#xff0c;可以分配简单数据类型&#xff08;POD&#xff09;的内存指针&#xff0c;但它是一个单件。 singleton_pool位于名字空间boost&#xff0c;为了使用singleton_pool组件&#xff0c;需要包含头文件<boost/p…...

腾讯云从业者认证考试考点——云网络产品

文章目录 腾讯云网络产品功能网络产品概述负载均衡&#xff08;Cloud Load Balancer&#xff09;私有网络&#xff08;Virtual Private Cloud&#xff0c;VPC&#xff09;专线接入弹性网卡&#xff08;多网卡热插拔服务&#xff09;NAT网关&#xff08;NAT Gateway&#xff09;…...

Miniled透明屏:超薄、轻便,还有哪些特点?

Miniled透明屏是一种新型的显示屏技术&#xff0c;它采用了微小的LED灯珠作为显示单元&#xff0c;通过透明的材料进行封装&#xff0c;使得整个屏幕具有透明的特性。Miniled透明屏具有以下几个特点&#xff1a; 首先&#xff0c;Miniled透明屏具有高亮度和高对比度的特点。 由…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...