【数据结构】初识链表

顺序表的优缺点

缺点:

  • 中间/头部的插入删除,时间复杂度效率较低,为O(N)

  • 空间不够的时候需要扩容。

    • 如果是异地扩容,增容需要申请新空间,拷贝数据,释放旧空间,会有不小的消耗。
  • 扩容可能会存在空间浪费。

    • 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

优点:

  • 尾差尾删足够快。
  • 下标的随机访问和修改足够快。

链表的初步认知

针对顺序表的缺点,链表就被设计出来了。
链表的特点即,按需申请释放。
当我们需要一块空间时,我们就申请一块空间。当我们需要添加数据时,就继续增加一个一个小块。
主要是就是一个一个小块之间的连接。为了方便连接和管理,每一个结点中都存有一个指针,用于指向下一个结点。正式一个一个“链接”起来,所以叫做链表。

下面图中主要标识了顺序表和链表的逻辑结构的不同。
对于顺序表,我们只需要知道指向这块内存空间的指针即可。
但是对于链表,我们仅仅知道指向第一块内存空间的指针是不够的,因为一块与一块之间没有连接。所以对于每一块,都必须存有指向下一块空间的指针。

定义单链表的结构

链表的逻辑图:

链表的物理图:

//Single List Table
typedef int SLTDataType;
typedef struct SListNode
{SLTDataType data;struct SListNode* next;//SLTNode* next 是不可以的
}SLTNode;

下面,我们再来写一个打印单链表的的函数。

void PrintSList(SLTNode* phead)
{SLTNode* p = phead;while (p != NULL){printf("%d ", p->data);p=p->next;}printf("NULL\n");
}

然后,接下来,我们再来在主函数中自己建一个单链表,其实也就是开辟几个结点的空间,然后使得结点之间可以“链接”起来即可。

int main()
{SLTNode* n1 = (SLTNode*)malloc(sizeof(SLTNode));n1->data = 1;SLTNode* n2 = (SLTNode*)malloc(sizeof(SLTNode));n2->data = 2;SLTNode* n3 = (SLTNode*)malloc(sizeof(SLTNode));n3->data = 3;n1->next = n2;n2->next = n3;n3->next = NULL;PrintSList(n1);
}

由上图,我们可以知道代码的逻辑。

  • 动态分配内存,创建3个 SLTNode 类型的节点,并将其地址赋值给指针 n1、n2、n3。
  • 然后将3个结点的next字段都赋值。
  • 然后将链表链接起来。
    • n1->next = n2;将节点 n1 的 next 指针指向节点 n2,表示 n1 的下一个节点是 n2。
    • n2->next = n3;将节点 n2 的 next 指针指向节点 n3,表示 n2 的下一个节点是 n3。
    • n3->next = NULL;将节点 n3 的 next 指针设置为 NULL,表示链表到此结束。
  • 最后打印链表。


我们进行逐语句调试,在监视窗口中观察n1,n2,n3的变化。

我们可以看出来,n1、n2 和 n3 的物理地址并不连续。
根据结构体的定义,我们可以计算出结构体的大小。

如果内存连续,地址应该是:

而根据我们的监视信息,并非连续,这正是因为在代码中使用了 malloc 动态分配内存。
malloc 从堆中分配内存,而堆内存的分配通常是非连续的,具体取决于系统内存分配器的实现和当前堆内存的使用情况。因此,动态分配的内存块通常在物理地址上是分散的。



这一篇小博客,我们认识链表,下面我们将接着实现链表。
加油!

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

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

相关文章

增删改查(CRUD)操作

文章目录 MySQL系列:1.CRUD简介2.Create(创建)2.1单行数据全列插入2.2 单行数据指定插入2.3 多⾏数据指定列插⼊ 3.Retrieve(读取)3.1 Select查询3.1.1 全列查询3.1.2 指定列查询3.1.3 查询字段为表达式(都是临时表不会对原有表数据产生影响)…

使用Pygame制作“贪吃蛇”游戏

贪吃蛇 是一款经典的休闲小游戏:玩家通过操控一条会不断变长的“蛇”在屏幕中移动,去吃随机出现的食物,同时要避免撞到墙壁或自己身体的其他部分。由于其逻辑相对简单,但可玩性和扩展性都不错,非常适合作为新手练习游戏…

JavaScript闭包深入剖析:性能剖析与优化技巧

一、引言 在 JavaScript 的奇妙世界里,闭包无疑是一个既强大又迷人的特性。它就像是一把万能钥匙,为开发者打开了实现各种高级功能的大门。从数据封装与保护,到函数的记忆化,再到模块化开发,闭包都发挥着举足轻重的作…

Java 泛型<? extends Object>

在 Java 泛型中&#xff0c;<? extends Object> 和 <?> 都表示未知类型&#xff0c;但它们在某些情况下有细微的差异。泛型的引入是为了消除运行时错误并增强类型安全性&#xff0c;使代码更具可读性和可维护性。 在 JDK 5 中引入了泛型&#xff0c;以消除编译时…

蓝桥杯嵌入式赛道备考1 —— 基础GPIO实战

1. 点亮一个LED 蓝桥杯的板子资料的URL&#xff0c;笔者是从GitHub - JoyRiderJie/LanQiaoBei-QianRuShi拉去下来的。这个是Github仓库地址。 从应用层去玩一个开发板子&#xff0c;首先需要的是去尝试是点亮一个LED。让我们切换到手册《CT117E——产品手册》的第11页&#x…

浅析DNS污染及防范

DNS污染&#xff08;DNS Cache Poisoning&#xff09;是一种网络攻击手段&#xff0c;通过篡改DNS服务器的缓存数据&#xff0c;将域名解析结果指向错误的IP地址&#xff0c;从而误导用户访问恶意网站或无法访问目标网站。这种攻击利用了DNS协议的特性&#xff0c;例如“只认第…

前端学习-事件解绑,mouseover和mouseenter的区别(二十九)

目录 前言 解绑事件 语法 鼠标经过事件的区别 鼠标经过事件 示例代码 两种注册事件的区别 总结 前言 人道洛阳花似锦&#xff0c;偏我来时不逢春 解绑事件 on事件方式&#xff0c;直接使用null覆盖就可以实现事件的解绑 语法 btn.onclick function(){alert(点击了…

AI编程:如何编写提示词

这是小卷对AI编程工具学习的第2篇文章&#xff0c;今天讲讲如何编写AI编程的提示词&#xff0c;并结合实际功能需求案例来进行开发 1.编写提示词的技巧 好的提示词应该是&#xff1a;目标清晰明确&#xff0c;具有针对性&#xff0c;能引导模型理解问题 下面是两条提示词的对…

R 字符串:深入理解与高效应用

R 字符串:深入理解与高效应用 引言 在R语言中,字符串是数据处理和编程中不可或缺的一部分。无论是数据清洗、数据转换还是数据分析,字符串的处理都是基础技能。本文将深入探讨R语言中的字符串概念,包括其基本操作、常见函数以及高效应用方法。 字符串基本概念 字符串定…

处理 .gitignore 未忽略文件夹问题

本地删除缓存 例如 .idea 文件夹被其他同事误提交&#xff0c;那么他本地执行以下代码 git rm -r --cached .idea对应本地再提交即可

linux asio网络编程理论及实现

最近在B站看了恋恋风辰大佬的asio网络编程&#xff0c;质量非常高。在本章中将对ASIO异步网络编程的整体及一些实现细节进行完整的梳理&#xff0c;用于复习与分享。大佬的博客&#xff1a;恋恋风辰官方博客 Preactor/Reactor模式 在网络编程中&#xff0c;通常根据事件处理的触…

【思维导图】并发编程

学习计划&#xff1a;将目前已经学的知识点串成一个思维导图。在往后的学习过程中&#xff0c;不断往思维导图里补充&#xff0c;形成自己整个知识体系。对于思维导图里的每个技术知识&#xff0c;自己用简洁的话概括出来&#xff0c; 训练自己的表达能力。 并发和并行的区别 并…

【B站保姆级视频教程:Jetson配置YOLOv11环境(四)cuda cudnn tensorrt配置】

Jetson配置YOLOv11环境&#xff08;4&#xff09;cuda cudnn tensorrt配置 文章目录 0. 简介1. cuda配置&#xff1a;添加cuda环境变量2. cudnn配置3. TensorRT Python环境配置3.1 系统自带Python环境中的TensorRT配置3.2 Conda 虚拟Python环境中的TensorRT配置 0. 简介 官方镜…

【深度分析】DeepSeek 遭暴力破解,攻击 IP 均来自美国,造成影响有多大?有哪些好的防御措施?

技术铁幕下的暗战&#xff1a;当算力博弈演变为代码战争 一场针对中国AI独角兽的全球首例国家级密码爆破&#xff0c;揭开了数字时代技术博弈的残酷真相。DeepSeek服务器日志中持续跳动的美国IP地址&#xff0c;不仅是网络攻击的地理坐标&#xff0c;更是技术霸权对新兴挑战者的…

DeepSeek R1功能设计涉及的几个关键词

DeepSeek R1作为人工智能助手&#xff0c;其功能设计主要基于以下步骤&#xff1a; 字典过滤与词汇选择 使用蒸馏技术对候选词汇进行筛选和优化&#xff0c;确保选择的词汇与上下文语境相关且准确。候选词汇通过多源数据&#xff08;如公开文档、专家分析等&#xff09;进行训练…

如何在数据湖中有效治理和管理“数据沼泽”问题,提高数据的可发现性和利用率?

在数据湖中有效治理和管理“数据沼泽”问题&#xff0c;提高数据的可发现性和利用率&#xff0c;需要从多个方面入手&#xff0c;包括数据治理、元数据管理、数据质量控制、安全性保障以及生命周期管理等。以下是具体的策略和方法&#xff1a; 1. 构建强大的数据治理框架 数据…

【4Day创客实践入门教程】Day3 实战演练——桌面迷你番茄钟

Day3 实战演练——桌面迷你番茄钟 目录 Day3 实战演练——桌面迷你番茄钟1. 选择、准备元件、收集资料2. 硬件搭建3.编写代码 Day0 创想启程——课程与项目预览Day1 工具箱构建——开发环境的构建Day2 探秘微控制器——单片机与MicroPython初步Day3 实战演练——桌面迷你番茄钟…

Oracle Primavera P6自动进行进度计算

前言 在P6 Professional 有一个自动计划计算的选项&#xff0c;很多人不了解该设置如何使用&#xff0c;以及什么时候该启动这项配置。 详情 P6 Professional 默认为非自动进度计算。启用自动选项后&#xff0c;可以快速查看调度更改的效果。 ​ ​ 如图所示&#xff0c;当你…

DeepSeek-R1 论文解读 —— 强化学习大语言模型新时代来临?

近年来&#xff0c;人工智能&#xff08;AI&#xff09;领域发展迅猛&#xff0c;大语言模型&#xff08;LLMs&#xff09;为通用人工智能&#xff08;AGI&#xff09;的发展开辟了道路。OpenAI 的 o1 模型表现非凡&#xff0c;它引入的创新性推理时缩放技术显著提升了推理能力…

舵机型号与识别

舵机型号繁多&#xff0c;不同品牌和制造商有不同的命名规则。常见的舵机品牌包括 Futaba、Hitec、Tower Pro、Savox、JX Servo 等。以下是舵机型号的常见识别方法以及一些典型的型号示例&#xff1a; 一、舵机型号的识别方法 型号命名规则&#xff1a; 舵机型号通常由字母和数…