“反正你又看不到,少写一行又何妨......”

单链表专题

  • 1.链表的概念及结构
  • 2. 实现单链表
  • 3. 链表的分类

1.链表的概念及结构

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

链表的结构跟火车车厢相似,淡季时⻋次的⻋厢会相应减少,旺季时⻋次的⻋厢会额外增加⼏节。只需要将⽕⻋⾥的某节⻋厢去掉/加上,不会影响其他⻋厢,每节⻋厢都是独⽴存在的。

⻋厢是独⽴存在的,且每节⻋厢都有⻋⻔。想象⼀下这样的场景,假设每节⻋厢的⻋⻔都是锁上的状态,需要不同的钥匙才能解锁,每次只能携带⼀把钥匙的情况下如何从⻋头⾛到⻋尾?
最简单的做法:每节⻋厢⾥都放⼀把下⼀节⻋厢的钥匙。

在这里插入图片描述
在这里插入图片描述

在链表⾥,每节“⻋厢”是什么样的呢?

在这里插入图片描述

与顺序表不同的是,链表⾥的每节"⻋厢"都是独⽴申请下来的空间,我们称之为“结点/节点”

节点的组成主要有两个部分:当前节点要保存的数据和保存下⼀个节点的地址(指针变量)。

图中指针变量 plist保存的是第⼀个节点的地址,我们称plist此时“指向”第⼀个节点,如果我们希望plist“指向”第⼆个节点时,只需要修改plist保存的内容为0x0012FFA0。

为什么还需要指针变量来保存下⼀个节点的位置?
链表中每个节点都是独⽴申请的(即需要插⼊数据时才去申请⼀块节点的空间),我们需要通过指针变量来保存下⼀个节点位置才能从当前节点找到下⼀个节点。

结合前⾯学到的结构体知识,我们可以给出每个节点对应的结构体代码:
假设当前保存的节点为整型:

struct SListNode
{
int data; //节点数据
struct SListNode* next; //指针变量⽤保存下⼀个节点的地址
};

当我们想要保存⼀个整型数据时,实际是向操作系统申请了⼀块内存,这个内存不仅要保存整型数据,也需要保存下⼀个节点的地址(当下⼀个节点为空时保存的地址为空)。
当我们想要从第⼀个节点⾛到最后⼀个节点时,只需要在前⼀个节点拿上下⼀个节点的地址(下⼀个节点的钥匙)就可以了。

给定的链表结构中,如何实现节点从头到尾的打印?

在这里插入图片描述

补充说明:
1、链式机构在逻辑上是连续的,在物理结构上不⼀定连续
2、节点⼀般是从堆上申请的
3、从堆上申请来的空间,是按照⼀定策略分配出来的,每次申请的空间可能连续,可能不连续

2. 实现单链表

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 SLTPrint(SLTNode* phead);//尾插
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);

Sllist.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");
}SLTNode* SLTBuyNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;return newnode;
}//尾插
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;}
}
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);//newnode *ppheadnewnode->next = *pphead;*pphead = newnode;
}
//尾删
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 ptailfree(ptail);ptail = NULL;prev->next = NULL;}
}
//头删
void SLTPopFront(SLTNode** pphead)
{//链表不能为空assert(pphead && *pphead);SLTNode* next = (*pphead)->next; //-> 优先级高于*free(*pphead);*pphead = next;
}
//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{SLTNode* pcur = phead;while (pcur)//等价于pcur != NULL{if (pcur->data == x){return pcur;}pcur = pcur->next;}//pcur == NULLreturn NULL;
}
//在指定位置之前插入数据
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 -> posnewnode->next = pos;prev->next = newnode;}
}
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = SLTBuyNode(x);//pos -> newnode -> pos->nextnewnode->next = pos->next;pos->next = newnode;
}
//删除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->nextprev->next = pos->next;free(pos);pos = NULL;}
}
//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos)
{assert(pos && pos->next);SLTNode* del = pos->next;//pos del del->nextpos->next = del->next;free(del);del = NULL;
}
//销毁链表
void SListDesTroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}//pcur*pphead = NULL;
}

test.c

#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);
}void SListTest02()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist); // 1->2->3->4->NULLSListDesTroy(&plist);SLTPrint(plist);//测试查找//SLTNode* find = SLTFind(plist, 1);//SLTInsert(&plist, find, 11);//SLTInsertAfter(find, 11);//删除pos节点//SLTErase(&plist, find);//SLTEraseAfter(find);//SLTPrint(plist);//if (find == NULL)//{//	printf("没有找到!\n");//}//else {//	printf("找到了!\n");//}//SLTPushBack(NULL, 5);////测试头插//SLTPushFront(&plist, 6);//SLTPrint(plist);//SLTPushFront(&plist, 7);//SLTPrint(plist);//SLTPushFront(&plist, 8);//SLTPrint(plist);//测试头删//SLTPopFront(&plist);//SLTPrint(plist);// 2->3->4->NULL//SLTPopFront(&plist);//SLTPrint(plist);//SLTPopFront(&plist);//SLTPrint(plist);//SLTPopFront(&plist);//SLTPrint(plist);//SLTPopFront(&plist);//SLTPrint(plist);}int main()
{//SListTest01();SListTest02();return 0;
}

3. 链表的分类

链表的结构⾮常多样,以下情况组合起来就有8种(2 x 2 x 2)链表结构:

在这里插入图片描述

链表说明:

在这里插入图片描述

虽然有这么多的链表的结构,但是我们实际中最常⽤还是两种结构:单链表和双向带头循环链表

  1. ⽆头单向⾮循环链表:结构简单,⼀般不会单独⽤来存数据。实际中更多是作为其他数据结
    构的⼦结构,如哈希桶、图的邻接表等等。另外这种结构在笔试⾯试中出现很多。
  2. 带头双向循环链表:结构最复杂,⼀般⽤在单独存储数据。实际中使⽤的链表数据结构,都
    是带头双向循环链表。另外这个结构虽然结构复杂,但是使⽤代码实现以后会发现结构会带
    来很多优势,实现反⽽简单了,后⾯我们代码实现了就知道了。

完。。。

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

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

相关文章

GraphQL API-通过未被净化的参数获取隐私信息

GraphQL API-通过未被净化的参数获取隐私信息 Lab: Accessing private GraphQL posts实验前置必要知识点 在GraphQL端点发送任何query{__typename}&#xff0c;它将在其响应中的某处包含{"data": {"__typename": "query"}}字符串&#xff0c;这…

JZM-A系列机械隔膜计量泵

引言&#xff1a; 在现代工业生产过程中&#xff0c;对流体材料的精准计量和输送需求日益提高。面对这一挑战&#xff0c;JZM-A系列机械隔膜计量泵以其卓越的设计、准确的计量能力和高效的性能&#xff0c;为各行各业提供了一种可靠的解决方案。本文将详细解析JZM-A系列计量泵的…

数字社交的新典范:解析Facebook的成功密码

在当今数字化时代&#xff0c;社交媒体已经成为人们日常生活的重要组成部分&#xff0c;而Facebook作为最知名的社交媒体平台之一&#xff0c;其成功之处备受瞩目。本文将深入解析Facebook的成功密码&#xff0c;探讨其在数字社交领域的新典范。 1. 用户体验的优化 Facebook注…

6.1Python之字典的初识

【1】字典的创建与价值 字典&#xff08;Dictionary&#xff09;是一种在Python中用于存储和组织数据的数据结构。元素由键和对应的值组成。其中&#xff0c;键&#xff08;Key&#xff09;必须是唯一的&#xff0c;而值&#xff08;Value&#xff09;则可以是任意类型的数据。…

ue4打包多模块

首先&#xff0c;每个模块&#xff0c;包含插件内的模块在内&#xff0c;都要用IMPLEMENT_MODULE(类名, 模块名)的方式&#xff0c;模块名就是带.build.cs的第一个单词。 build.cs里就说了这个模块该怎么用&#xff0c;用c#编写。 打包中要考虑到target.cs,将工程中相应的模块…

花花省V6淘宝客APP社交电商自营商城聚合优惠券系统

首页广告位、淘口令识别、微信登录、淘宝登录、淘宝返佣、拼多多返佣、京东返佣、唯品会返佣、热销榜、聚划算、天猫超市、9.9包邮、品牌特卖、新人攻略 、小米有品、优惠加油、阿里巴巴、去哪网、电影票、飞猪旅行、美团酒店、当当网、肯德基、热门抖货、商品推荐、商品详情、…

基于Springboot + vue +MySQL 留守儿童爱心网站 (含源码)

目录 &#x1f4da; 前言 &#x1f4d1;摘要 &#x1f4d1;系统架构 &#x1f4da; 数据库设计 &#x1f4ac; 志愿活动属性图 &#x1f4ac; 爱心捐赠实体属性 &#x1f4da; 系统功能的具体实现 &#x1f4ac; 系统功能模块 宣传新闻 志愿活动 &#x1f4ac; 管理员功…

基于java+springboot+vue实现的售楼管理系统(文末源码+Lw)23-255

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本售楼管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&a…

312_C++_QT表格的剪切、拷贝、粘贴,轻量化操作

:拷贝 + 粘贴 :剪切 + 粘贴 void CustomTableWidget::cut() {copy();// 获取所有选定的单元格项QList<QTableWidgetItem*> selectedItemsList

SpringBoot学习之Kibana下载安装和启动(三十二)

一、简介 Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据。Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图等,直观的展示数据,从而达到高级的数据分析与可视化的目的。 …

Java springmvc 参数名用is开头导致为null

因为最近在整理一些源码和编写规范&#xff0c;这里写一下只是记录几年前自己遇到的问题&#xff0c;好久都忘了&#xff0c;还是写下来比较好。 问题记录&#xff1a;由于变量使用了boolean&#xff0c;并且变量名是is开头的&#xff0c;由于java机制boolean默认是false&#…

FASTAPI系列 20-异常处理器exception_handler

FASTAPI系列 20-异常处理器exception_handler 文章目录 FASTAPI系列 20-异常处理器exception_handler前言一、HTTPException 异常&#xff1f;二、覆盖默认的HTTPException 异常三、覆盖请求验证异常RequestValidationError 源码分析 总结更多内容&#xff0c;请关注公众号 前言…

GET与POST:详述HTTP两大请求方法的语义、数据处理机制、安全特性与适用场景

GET和POST方法在HTTP请求中具有明确的角色分工和特性差异。GET适用于读取操作和不敏感数据的传递&#xff0c;强调可缓存性和安全性&#xff0c;而POST适用于写入操作和敏感数据的提交&#xff0c;提供了更大的数据承载能力和更强的隐私保护。本文详细介绍了GET与POST请求方法的…

多张固定宽度元素,随着屏幕尺寸变化自动换行

背景&#xff1a;多张固定宽度元素&#xff0c;随着屏幕尺寸变化自动换行实现&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevic…

多协议接入视频汇聚EasyCVR平台vs.RTSP安防视频EasyNVR平台:设备分组的区别

EasyCVR视频融合云平台则是旭帆科技TSINGSEE青犀旗下支持多协议接入的视频汇聚融合共享智能平台。平台可支持的接入协议比EasyNVR丰富&#xff0c;包括主流标准协议&#xff0c;有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海…

Java 集合Collection

集合的体系 Collection的结构体系 List系列集合&#xff1a;添加的元素是有序的、可重复、有索引。Set系列集合&#xff1a;无序、不重复、无索引 HashSet&#xff1a;无序、不重复、无索引LinkedHashSet:有序、不重复、无索引TreeSet&#xff1a;按照大小默认升序排序、不重复…

VueRouter使用,界面切换

一、安装 vue-router3&#xff0c;4分别对应vue2&#xff0c;3.。我现在用的是vue2&#xff0c; npm install vue-router3二、使用 ①首先在component路径下提前写好需要渲染的组件。 ②在App.vue中使用router声明路由。其中router-link的to指明渲染哪一个组件。router-view…

从零开始学Spring Boot系列-SpringApplication

SpringApplication类提供了一种从main()方法启动Spring应用的便捷方式。在很多情况下&#xff0c; 你只需委托给 SpringApplication.run这个静态方法 &#xff1a; SpringBootApplicationpublic class SpringbootLearningApplication {public static void main(String[] args) …

【MYSQL锁】透彻地理解MYSQL锁

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 目录 1.锁 1.1 概述 1.2 全局锁 1.2.1 语法 1.2.1.1 加全局锁 1.2.1.2 数据备份 1.2.1.3 释放锁 1.2.1.4 特点 1.2.1.5 演示 1.3 表级锁 1.3.1 介绍 …

HTTP与HTTPS:深度解析两种网络协议的工作原理、安全机制、性能影响与现代Web应用中的重要角色

HTTP (HyperText Transfer Protocol) 和 HTTPS (Hypertext Transfer Protocol Secure) 是互联网通信中不可或缺的两种协议&#xff0c;它们共同支撑了全球范围内的Web内容传输与交互。本文将深度解析HTTP与HTTPS的工作原理、安全机制、性能影响&#xff0c;并探讨它们在现代Web…