关于数据结构的学习心得

news/2024/10/6 3:40:02/文章来源:https://www.cnblogs.com/Athanasy/p/18288795

介绍

在备赛 xcpc 时,其实除了数据结构以外,绝大部分常用的大纲知识都学习了,但数据结构确实是练得最多的,本文主要介绍一下个人是如何学习数据结构的。

数据结构概述

数据结构大概是很多人比较抵触系统学习的东西,因为许多数据结构来说,光是板子就比其他领域的算法长很多。比如线段树,可能是很多人从数据结构新手前往数据结构殿堂遇到的一道很大阻碍。

当然了,学习数据结构也不只有数据结构题,数据结构往往可以去优化许多其他算法,比如 \(dp\) 问题,\(2-SAT\) 优化建图问题等等。

数据结构的考量

我个人觉得对于一个人的数据结构的水平体现为以下几点:

  1. 码力,是否有着良好的调试代码能力,是否具备所想即可正确使用代码实现的能力。

  2. 抽象思维,对于数据结构来说,本质上就是维护信息的东西,那么维护什么样的信息是需要你去思考的,如何把一个题抽象出数据结构,着重于分析维护信息。

  3. 经验,我认为学习数据结构离不开经验,是需要大量地练习。大量的练习可以让你积累许多经验,使得第一点,你可以比较清楚怎样的语法去实现是比较容易调试和分析的,第二点则你可以反应出需要设计怎样的信息:最常见的例子,我们多维护前缀最值之类的具有单调性的信息可以实现树上二分。

  4. 实现能力,许多人学习各类的数据结构喜欢停留在思维概念上。比如线段树的大致思想知道,但并没有去实现,对于数据结构来说,可能一个函数有各种不同的写法,有着各种不同的优势,就比如线段树的查询来说:分为了 需要临时变量合并信息/不需要临时变量合并信息,后者则可以更好地使用结构体重载运算符快速地书写复杂的信息合并。

  5. 知识储备,数据结构离不开知识储备,就比如很多人认为学习了线段树以后,学习 \(ST\) 表、猫树之类的数据结构是无用的。每一种数据结构都有它所擅长的优势领域,当如果你在写过大码题,显然一个更小的常数的数据结构可以使得你的代码更不容易被卡常。

  6. 理性思考,数据结构不同于其他算法,必须理性思考问题:\(\log^2{n}\)\(\log{n} \times \log{V}\) 看似都是双 \(\log\),但它们的空间和时间常数远远不同,这个过程中,你不能想当然的大致时间复杂度而忽略二者的差异。比如树套树当中,你内层树的值域并不离散化,那么线段树套值域线段树的空间可能会远远超过 \(1G\),但离散化后可能才 \(400mb\)

  7. 无他,惟手熟尔是数据结构的殿堂进步的捷径。对于初学者来说,万万不可以太过依赖于模版,否则学习更深层的数据结构当中,会出现很多疑惑点,比如线段树合并、可持久化线段树、动态开点线段树等等。当你如果能快速书写一个线段树的代码,那么你可以从代码当中体会到信息的维护过程,从而具备抽象思考的能力,当然线上赛追求速度可以考虑使用板子,学习的时候尽量多写写,因为写法不止一种,每个人有最适合自己的写法,并且写多了踩坑多了,会学习到每种题的经验。

数据结构学习的道路

学习数据结构离不开一条成熟的路线指引,对于不同需求的选手,有着不同的推荐指南。

我们需要清楚,常见的数据结构无非分为三个方向:序列上问题、树上问题、图上问题。

对于这三个方向的问题可以分别练习,并且有许许多多的技巧都是书上不会讲到的。

  1. STL 容器。虽然这东西是 C++ 的,但并不妨碍它类比到其他语言。首先最常见的就是:队列、栈、堆。这三个无论如何都需要学习好它们的概念和特点,因为它们将会伴随着你的整个数据结构生涯,需要特别熟练掌握。其次,学习哈希表是很有必要的,很多人把 \(map\) 当哈希表是完全不正确的,哈希表是 \(key\) 是无序的,是存在哈希冲突的,我们常常会使用手写哈希解决,这点可以参照 oiwiki,或者使用 \(pbds\) 的哈希表,更不容易哈希冲突且更快。关于内置的平衡树,因语言不同,那么在此不详细讨论,但一些基本概念比如 \(map\) 底层是红黑树,修改和查询都带 \(\log{n}\) 是需要知道的。

  2. 基于基本容器的数据结构。这类既算算法,也算数据结构,常见的有单调栈、单调队列。这是必须掌握的东西,并且概念学习明白。除此之外,例如懒删除堆、对顶堆的技巧可视个人能力进行选择性学习。

  3. ST 表。这个我个人认为是很有必要学习的,相信每个人都会接触到基础算法,那么一定会学习 倍增与快速幂,在基于倍增理念的基础上,学习 \(ST\) 表的成本是很低的,并且你这也将成为你数据结构历程上第一个学习到的非常有用的静态非可差分性问题的数据结构。当然了关于它的拓展:\(2\) 维 ST 表、尾部新增元素更新、分块 ST 表、四毛子算法之类的可视自身能力掌握。它也是解决 \(RMQ\) 问题的最常见手段之一,它的常数小,代码短,是属于新手学习数据结构的一个很好的 跳板

  4. 并查集。这个是属于贯彻数据结构一生都必不可缺少的东西,关于它你需要把所有东西全部学完:按秩合并、启发式合并、路径压缩、如何实现带权信息合并、可撤销并查集、种类并查集(扩展域并查集)、可持久化并查集(选学)。其中可撤销并查集是你通往高级数据结构之路一个必不可缺的东西,它体现了一类经典的技巧-----回滚思想,这类思想将伴随着你遇见的问题增多而有更深的体会。

  5. 字典树。这个没啥好说的,是于字符串当中好学又好写的东西,同时学习 \(01\) Trie,为未来的位运算问题的题进行铺垫,关于它的可持久化属于选学,并不是很难,频率较低,其余技巧比如全局 \(+1\) 这些,属于 \(ynoi\) 类的题当中会遇到的了。

  6. 树状数组。这是你迈向高级数据结构的入门,你需要把这个数据结构反复学习,不断学习。关于它,你要开始正式思考数据结构维护的是哪一维信息,不同维需要进行怎样的不同处理。当然了,在这当中,你也可以学习一些比较好用的技巧,比如基于哈希表的动态开点树状数组、树状数组上倍增等等。对它的评价为:其实就是维护 动态前缀信息

  7. 线段树。大概是很多人会用一辈子的数据结构。首先学习关于树的基本相关知识,了解线段树是一棵完全二叉树。其次理解线段树如何维护区间信息的,常见是如何实现的?不同的人有不同的实现风格,初学者可以先自行学习任意一种实现方式。学习基本的单修区查线段树,建议反复练习十遍左右。然后应该学习懒标记的线段树,在这个过程中,建议做做一些板子题。然后关于线段树的进阶其实并不需要太过着急,可以先从动态开点的线段树进行学习,然后线段树分裂、合并、二分这个建议系统性学习,配合题目进行练习。

  8. 可持久化类数据结构。关于主席树是必学的,不用想着被替换,有时候离线难写的很,这东西学习成本低,如果前几点学明白了,学这个很快。至于可持久化的其他的属于选学,学习性价比并不高,可持久化的平衡树蓝桥杯倒是考过。

  9. 平衡树与文艺平衡树。我更愿意把这二者分开,前者是维护关于权值类的序,后者则是下标的序。后者可以看做另一种线段树,但能做的奇怪操作比线段树更多,空间比线段树更小。关于平衡树,我绝大部分都学习过了,个人推荐学习 \(fhq\)\(splay\) 即可,其余的性价比并不高。

  10. 笛卡尔树。如果你学习了平衡树,建议把这个还是顺带学习,就一个单调栈建树,化 \(RMQ\) 问题为树上的 \(LCA\) 问题,很方便一道堆关于 \(max/min\) 之类的区间数量统计。

  11. 树链剖分。重链剖分是比较有必要学习的,属于很板子的东西,学懂了序列上的,这个东西自然而然就会了。长链剖分较冷门,一般用于优化 dp 的,属于选学。虚实链剖分即为动态树。

  12. 动态树。学习 \(LCT\) 其实就够了,\(GBT\)\(Top Tree\)\(ETT\) 属于如果想要拓展学习再进行学习。动态树其实码量不大,思考起来常见的是基于容斥思考,容斥设计信息,有余力可以学习:动态 dp、动态 MST等等之类的信息。

  13. 点分治/点分树/树上启发式合并,做树上大规模查询问题会用到,常见的树上启发式合并比较好学,解决子树类问题,顺便建议学习一下 dfs 序的基本概念。点分治、点分树解决大规模树上路径统计,专题练习即可。

  14. 猫树。选学,是用来解决静态分治问题,它的理念比较像 \(zkw\) 线段树,可以选学。

  15. 分块。分块是很有必要学的,当你打算进阶 \(ynoi\) 的一些大数据结构题,分块是必不可少的一步,学习方式和线段树类似,但有很多额外需要学习的:值域分块、序列分块套值域分块等等。

  16. 莫队。个人建议必学的关于查询问题的妙手。要想学好莫队,使得自身不会只写板题,那么一定要学习可撤销的概念,学习:值域分块、回滚莫队、带修莫队、莫队二次离线。普通莫队用处较小,树上莫队其实常见的树上问题解决工具太多了,性价比也低。

  17. 势能 ds。这类问题比较特别需要单独练习才行,其实题目也较少,主要为洛谷的 bzoj 上的题。如果想要学习更难的势能线段树的题,可以学习吉司机线段树、KTT 之类的。

  18. 字符串的自动机部分,ACAM 是很有必要学的。如果是想打 xcpc 的,可以把后缀系列的学一下,pam 也可以学一下。常见的其实可以转化为树上问题

  19. 关于计算几何,李超树和凸包可以都掌握,半平面交可以考虑选学。前两个很有用,可以都学学,基本入门倒是不难。

  20. 虚树。虚树是一个比较好用的东西,其实学习难度不大,如果你有笛卡尔树的建树基础的话,应该能快速掌握,主要是应用于加快树上 dp 的。

  21. 树套树还是可以学学,归并树之类的都比较好用好写。

  22. 其余杂 ds,析合树可以学学,解决排列问题可以的。

关于数据结构平台练习

LeetCode 的话其实不太适合练习数据结构的码工,但上面的数据结构专栏有不少题比较适合新手,新手可以自行练习。洛谷上有许多模版数据结构题,可以考虑先刷熟练模版题再考虑进行其余题练习,其余题其实可以考虑罗勇军的 <<算法竞赛>> 这本书中的高级数据结构专栏课后习题进行选择练习。关于 atcoder 的话,可以把 abc 的 G 题单独拿出来,筛选数据结构的题,那些都是比较常见的应用练习。关于 cf,可以使用 ACD,在上面筛选 \(2000 \sim 2400\) 的数据结构题进行练习。

关于 cf 的 \(2800+\) 的数据结构题,大部分具有技巧性,对码工的要求并不是很高,可以单独作为知识点进行学习。对于洛谷的 \(Ynoi\) 专栏,可以选择性练习,大部分比较需要具备卡常能力以及码工。

关于数据结构还有许多一些技巧性的东西,比如离线扫描线、整体二分、cdq 分治之类的等等,都是有必要在学有余力的时候进行学习。当知识储备差不多的时候,可以考虑筛选 ccpc 各个省的省赛题中的 ds 题进行练习。当感觉能力足够的情况下,可以做做 icpc 区域赛相关的 ds 题进行挑战。

总结

数据结构的学习是比较枯燥的,需要静下心来去学,本文也只是心得分享,并未标出每个知识点需要学习的对应题,可能后续会为每个知识点挑选合适的题型进行整理,辅助各位更好地学习,数据结构中有许许多多的技巧,比如如何线段树只需要 \(O(n)\) 空间完成所有查询、如何实现正难则反、可差性转化等等,都是需要进行大量的练习和学习。

如果要学习基础的数据结构教程,可以关注我的 b站账号 Athanasy算法,基础数据结构教程将会持续更新,区别于其他教程,主要讲解代码实现与细节,还有实用性。

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

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

相关文章

markdowm语法Typora练习草稿

目录这是一级标题 这是一级标题 【Typora 教程】手把手教你如何用Typora撰写笔记_哔哩哔哩_bilibili 这是第一行 这是第二行 这是一个段落 这是一个段落这是粗体 这是斜体 这是删除线 这是下划线 这是高亮 格式里面有快捷键 1*2*3*4*5 x2 H2O一级分类二级分类三级分类tab 键 升…

视野修炼-技术周刊第91期 | 惊讶线条

① 漫画:浏览器的 UA 为什么这么长? ② 500+种js方法实现页面重载 ③ CSS 实现惊讶线条 ④ onefetch - 本地仓库信息查看工具 ⑤ StarFlare - 管理 Star 的项目 ⑥ 开源项目落地页模板 ⑦ 纯CSS鉴别是不是Safari浏览器 ⑧ 使用 MarsCode IDE 搭建 VitePress博客并使用 GitHub…

SpringBoot3 整合 Logback

SpringBoot3 整合 Logback 日志框架1. 默认框架实现 SpringBoot3 默认是使用 SLF4J + Logback 作为默认的日志门面和实现,但也支持其他日志系统,如 Log4j2、JUL (Java Util Logging), 这是通过所谓的日志门面实现的,开发者可以根据自己的需求选择合适的日志实现框架进行配置…

[LeetCode] 238. Product of Array Except Self

坑真的很多,首先要处理全零reduce没有值typeerror的问题。 class Solution:def productExceptSelf(self, nums: List[int]) -> List[int]:total=reduce(mul, nums)ret =[]if total == 0:try:total = reduce(mul, [x for x in nums if x != 0]) except TypeError:#default v…

灰色预测代码的讲解

本章通过一个例题,来讲解灰色预测代码。由于笔者只是以学习者的身份,以做笔记为目的写这篇博客,因此欢迎大家学习交流,代码(非本人所写)会附在最后面 目录一、总述————如何处理预测题目?1.画出时序图,分析趋势2.检验与比较模型————训练与试验3.得出结论————…

CRT工具

CRT工具 传输位置设置打开SFTP alt + p 命令 ls:远程机器当前目录内容 lls:传输位置文件的目录内容 pwd:远程机器的当前位置 lpwd:传输位置的位置 get 文件:ftp传输文件 get -r 文件夹:ftp传输文件夹 put 文件:ftp传输文件 put -r 文件夹:ftp传输文件夹 lrm -rf 文件/文…

硬件开发笔记(二十三):贴片电阻的类别、封装介绍,AD21导入贴片电阻原理图封装库3D模型

前言电阻,电容,电感还有各种基础的电子元器件、连接器和IC构成了各种实现功能的电子电路。  本篇介绍贴片电阻,并将贴片电阻封装导入AD21,预览其三维模型。 贴片电阻贴片电阻(SMD Resistor)作为一种不可或缺的电子元件,广泛应用于各种电路和设备中。其体积小、重量轻、…

EtherCAT转Profinet网关配置说明第三讲:博图配置

XD-ECPNS20网关模块实现EtherCAT与Profinet协议转换设备,简化工业控制系统建设与维护。EtherCAT协议转Profinet协议网关模块是实现EtherCAT协议和Profinet协议之间无缝通讯的重要设备。使EtherCAT协议和Profinet协议能够相互转换,进行工控自动化里的互连和传送数据。EtherCAT…

第一周学习报告

在第一周,对Java进行初步了解,学习了Java的一些基础知识。学习主要参考于B站上的黑马程序员,以下为这周的学习报告 day1 打开CMD 1.win+r 2.输入CMD常见的CMD命令 1.盘符名称+冒号 盘符切换 2.dir 查看当前路径下的内容 3.cd目录 进入单级目录 4.cd .. 回退到上一级目录 5.c…

Linux 提权-SUID/SGID_2

本文通过 Google 翻译 SUID | SGID Part-2 – Linux Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。导航0 前言 1 上文回顾 2 枚举自定义 SUID 二进制文件 3 利用 SUID 二进制文件 – 共享对象注入3.1 使用 Strings …

配置与管理squid代理服务器

应用背景如下图所示, 公司用squid作代理服务器,代理服务器内网IP地址为192.168.200.1,外网IP为192.168.200.3公司内网所用IP地址段为192.168.200.0/24,并且想用8080作为代理端口。1: 配置非透明代理 1.1 、配置主机网络 准备三台Linux主机,第一台为外网主机名为www,网卡…

RedHat7.4—配置常规网络

配置主机名 把主机名修改为hyborn 方法一、使用nmtui修改主机名 需要管理员权限运行su -root输入root密码后进入管理员模式 运行nmtui通过上下左右选择菜单栏回车选择,进入设置系统名即可设置确定后退出 运行hostnamectl status 命令查看主机名,查看到的主机名,即可以看到St…