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

数据结构与算法这么难,为什么我们还要学习?

文章目录

  • 前言
  • 1. 数据结构与算法是什么?
  • 2. 为什么数据结构与算法很难?
  • 3. 如何系统学习数据结构与算法?
    • 🍑 复杂度
    • 🍑 线性表
    • 🍑 树形结构
    • 🍑 图
    • 🍑 排序
    • 🍑 字符串
    • 🍑 跳表与哈希表
    • 🍑 总结
  • 4. 学前勉言


前言

提到数据结构与算法,就一定会伴随着诸多所谓的坚持和抱怨。同时,还有两个词总是出现,一个是内功,是对知识的定位,一个是吃透,是对自己的期待。可是,我们是不是被这两个词束缚太久了,以至于出现了很多的问题:

  • 时间不多,数据结构与算法的知识体系庞大,总是学了后面忘了前面,很难坚持。
  • 刷了不少题,但面对面试官的提问和新的题目,我总是没有思路。
  • 代码细节总是写不对,环境、语言都可能成为我的 “绊脚石”。
  • 书上的东西看是看懂了,但到底要怎么实践?

在这里插入图片描述

我个人觉得,其实真正的原因是你没有找到好的学习方法,没有抓住学习的重点。实际上,数据结构和算法的东西并不多,常用的、基础的知识点更是屈指可数。只要掌握了正确的学习方法,学起来并没有看上去那么难,更不需要什么高智商、厚底子。

1. 数据结构与算法是什么?

从广义上讲,数据结构就是指一组数据的存储结构。算法就是操作数据的一组方法。

图书馆储藏书籍你肯定见过吧?为了方便查找,图书管理员一般会将书籍分门别类进行 “存储”。按照一定规律编号,就是书籍这种 “数据” 的存储结构。
 
那我们如何来查找一本书呢?有很多种办法,你当然可以一本一本地找,也可以先根据书籍类别的编号,是人文,还是科学、计算机,来定位书架,然后再依次查找。笼统地说,这些查找方法都是算法。

从狭义上讲,是指某些著名的数据结构和算法,比如队列、栈、堆、二分查找、动态规划等。这些都是前人智慧的结晶,我们可以直接拿来用。我们要讲的这些经典数据结构和算法,都是前人从很多实际操作场景中抽象出来的,经过非常多的求证和检验,可以高效地帮助我们解决很多实际的开发问题。

那数据结构和算法有什么关系呢?为什么大部分书都把这两个东西放到一块儿来讲呢?

这是因为,数据结构和算法是相辅相成的。数据结构是为算法服务的,算法要作用在特定的数据结构之上。 因此,我们无法孤立数据结构来讲算法,也无法孤立算法来讲数据结构。

比如,因为数组具有随机访问的特点,常用的二分查找算法需要用数组来存储数据。但如果我们选择链表这种数据结构,二分查找算法就无法工作了,因为链表并不支持随机访问。

数据结构是静态的,它只是组织数据的一种方式。如果不在它的基础上操作、构建算法,孤立存在的数据结构就是没用的。

现在你对数据结构与算法是不是有了比较清晰的理解了呢?有了这些储备,下面我们来看看,数据结构与算法的难点在哪儿吧。

2. 为什么数据结构与算法很难?

第一个问题:都说这部分知识是内功,一定要不断修炼,保证吃透,可是何为内功?何为吃透?

有人把学习数据结构与算法比喻为练内功,但我不赞成这样的说法。程序员真正的内功其实是解决复杂问题的全局把控能力以及细节实现能力,这往往需要十数年甚至数十年的持续修炼才能体会得到。除非你将所有计算机基础知识都称为内功,否则这样的比喻并不恰当。

不可否认的是,数据结构和算法方面的知识是计算机的基础知识之一,但是,这不意味着你一定要给它贴上一个宏大的标签,甚至扛着极大的心理压力和包袱去学习。

数据结构和算法方面的知识博大精深,深入挖掘下去还会用到许多数学知识。因此,我们的首要目标不应该是吃透,而应该是尝一尝,把知识读薄,指向实践,够用即可。后续要在某个非常具体的数据结构或者算法领域取得一定成就,才会需要吃透其中的一些东西。

第二个问题:怎么分配系统学习和刷题的时间呢?

有一句话很重要,做选择之前要明白自己到底想要什么。

刷题,基本都是为了应付面试。如果非要说是为了锻炼解决问题的思维能力,以及快速用合适的数据结构去解决现实中的问题,这个作用当然也有,但却是次要的。对于软件工程师来讲,还有很多比数据结构更重要的知识需要去学会。

如果你确定要去某个大厂应聘某个算法岗,而该算法岗是需要你刷题的,那么你就在系统学习之后,在网上找找相关的试卷或者考题,有目的地到 LeetCode 上去刷。

如果你不去大厂或者并不去应聘一些专门的算法岗职位,那么直接去系统学习一门课就好。把时间节省出来好好学些更重要的知识吧。切记,时间对于软件开发工程师非常非常珍贵,甚至是你最珍贵的资源、最宝贵的财富。千万不要大手大脚的占用大量时间去学习太多没必要的知识。

一言以蔽之,也就是没有孰重孰轻,但 系统的学习是刷题的基础。想象一下,你会在不认识汉字的情况下去读小说吗?

越是大而全,越要删繁就简卸下了包袱,明确了目标,接下来的问题就是怎么学习了。

很多同学感觉到自己的时间有限,数据结构和算法知识体系太过庞大,学了后面忘了前面,很难坚持学完。造成这种情况的原因很多,比如有些资料把简单问题复杂化了,有些资料则非常晦涩,数学知识过多,学术性过强,甚至是表达不清,很难让人有舒适的学习体验。

不论你是否已经具备了一定的基础,接下来,就让我们放平心态,先来梳理下在每个模块的学习目标到底是什么。

3. 如何系统学习数据结构与算法?

为了让大家对数据结构和算法能有个全面的认识,我画了一张图,里面几乎涵盖了所有数据结构和算法书籍中都会讲到的知识点。

在这里插入图片描述

🍑 复杂度

数据结构和算法解决的是如何更省、更快地存储和处理数据的问题,因此,我们就需要一个考量效率和资源消耗的方法,这就是复杂度分析方法。

所以,如果你只掌握了数据结构和算法的特点、用法,但是没有学会复杂度分析,那就相当于只知道操作口诀,而没掌握心法。只有把心法了然于胸,才能做到无招胜有招!

因此,复杂度分析这个内容,一定要花大力气来啃,必须要拿下,并且要搞得非常熟练。否则,后面的数据结构和算法也很难学好。

🍑 线性表

学习任何知识都要由浅入深,由易到难。线性表会是本专栏讲解的第一个数据结构,和其它结构相比,它更为简单直接,也最好理解,从代码实现上也最容易,是学习其他更复杂数据结构的基础。同样,也一定能让你对之后的学习更有信心。

🍑 树形结构

不过,在一些复杂的领域中,线性表这种简单的数据结构还不足以表达问题,这个时候,树形结构就出现了。

它是算法面试中最常出现的数据结构,也是在实际开发中我们经常会有意无意用到的数据结构,想要写出正确且更高效的程序代码,这部分的内容还是要打好基础的。

🍑 图

图是比树形结构更复杂的数据结构。如果说树形结构的应用往往体现在程序编写中,那么对图的应用往往更接地气,更体现在实际生活中。

比如可以通过图来解决找出两个城市之间如何行走距离最短、最节省时间、花费的金钱最少问题等等,还可以用图来估算一个工程能否按顺序进行以及估算该工程需要的最短时间。

🍑 排序

我们知道,数据结构是为算法服务的。所以在讲解完线性表、树形结构、图这三种数据结构后,我们正式进入到算法知识的讲解中。

在各种算法知识中,尤其以排序算法最经典,实用且在面试中最常出现。排序算法有十数种,每种排序算法的适用场合、时间以及空间复杂度、稳定性等各不相同,搞定了这部分的内容,也就可以应付面试了。

🍑 字符串

这种数据结构非常常见,同时也有着广泛的应用,比如在搜索引擎中搜索的关键词、在文章中需要过滤的敏感词等等,都属于字符串。

其中,最需要解决的问题是子串在整个字符串中的查找问题。主要介绍两种查找子串的算法实现方式。第一种实现方式称为朴素模式匹配算法,容易理解但执行效率相对较低;第二种是 KMP 模式匹配算法,这种算法执行效率很高,但理解起来却颇有难度。

尤其值得注意的是,有些面试官非常喜欢考 KMP 模式匹配算法实现的子串查找,这里的重要程度也就不言而喻了。

🍑 跳表与哈希表

跳表与哈希表这两种数据结构都非常实用且有趣味性,可以理解成是属于更高级的数据结构范畴。不过放心,虽然高级,但代码实现上却没有那么复杂。

你可以把跳表看作强化版的线性表,可以极大提升元素查询速度。而哈希表是对数组的扩展,对于查找操作同样有非常良好的性能表现。引入这两个话题,一是为了丰富你的眼界和开发思路,以备在日后的开发中随时采用,二来也是避免不了的老调重弹 —— 为了应付面试的需要。

🍑 总结

作为初学者,或者一个非算法工程师来说,你并不需要掌握上图里面的所有知识点。很多高级的数据结构与算法,比如二分图、最大流等,这些在我们平常的开发中很少会用到。所以,你暂时可以不用看。咱们学习要学会找重点。如果不分重点地学习,眉毛胡子一把抓,学起来肯定会比较吃力。

所以,只要集中精力逐一攻克这下面知识点就足够了。

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树;
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法。

掌握了这些基础的数据结构和算法,再学更加复杂的数据结构和算法,就会非常容易、非常快。

学习数据结构和算法的过程,是非常好的思维训练的过程,所以,千万不要被动地记忆,要多辩证地思考,多问为什么。如果你一直这么坚持做,你会发现,等你学完之后,写代码的时候就会不由自主地考虑到很多性能方面的事情,时间复杂度、空间复杂度非常高的垃圾代码出现的次数就会越来越少。你的编程内功就真正得到了修炼。

4. 学前勉言

前面划了学习的重点,也讲了学习这门课需要具备的基础。现在我就给你分享一下,本专栏 「数据结构」 学习的一些技巧。掌握了这些技巧,可以让你化被动为主动,学起来更加轻松,更加有动力!

  • 边学边练,适度刷题
  • 多问、多思考、多互动
  • 打怪升级学习法
  • 知识需要沉淀,不要想试图一下子掌握所有

在学习的过程中,一定会碰到 拦路虎。如果哪个知识点没有怎么学懂,不要着急,这是正常的。因为,想听一遍、看一遍就把所有知识掌握,这肯定是不可能的。学习知识的过程是反复迭代、不断沉淀的过程。

因此,我特别希望这个专栏 「数据结构」 不仅能帮你抛下身上对于数据结构与算法的沉重包袱,更能潜移默化地为你打开思维,建立数据结构与算法的敏感度,为之后的每一次实战打下坚实的基础。

要记住,数据结构与算法,本来就是一件小事。

相关文章:

数据结构与算法这么难,为什么我们还要学习?

文章目录前言1. 数据结构与算法是什么?2. 为什么数据结构与算法很难?3. 如何系统学习数据结构与算法?🍑 复杂度🍑 线性表🍑 树形结构🍑 图🍑 排序🍑 字符串🍑…...

剑指 Offer 52. 两个链表的第一个公共节点

摘要 剑指 Offer 52. 两个链表的第一个公共节点 一、双指针解法 使用双指针的方法,可以将空间复杂度降至 O(1)。只有当链表 headA headB都不为空时,两个链表才可能相交。因此首先判断链表 headA和 headB是否为空,如果其中至少有一个链表为…...

可以写进简历的软件测试电商项目,不进来get一下?

前言 说实话,在找项目的过程中,我下载过(甚至付费下载过)N多个项目、联系过很多项目的作者,但是绝大部分项目,在我看来,并不适合你拿来练习,它们或多或少都存在着“问题”&#xff…...

蓝桥杯-算法-印章问题

这个题真的顶啊!思路:n种图案,m张印章,每一个图案的概率是1/n,这个概率以后用P表示首先我们定义dp[i][j]是买了i张印章(对应于上面的m),凑齐j种图案的概率(对应于上面的n…...

戴尔游匣G16电脑U盘安装系统操作教程分享

戴尔游匣G16电脑U盘安装系统操作教程分享。有用户在使用戴尔游匣G16电脑的时候遇到了系统问题,比如电脑蓝屏、自动关机重启、驱动不兼容等问题。遇到这些问题如果无法进行彻底解决,我们可以通过U盘重新安装系统的方法来解决,因为这些问题一般…...

2023数学建模美赛赛题思路分析 2023美赛 美国大学生数学建模数模

将在本帖更新2023美国大学生数学建模数模美赛各个赛题思路,大家可以点赞收藏! 一、参赛报名 组队参赛(每队人数3人,专业不限)。 二、赛题思路及资料 会在本帖更新思路分析,Q群可领取模型代码/赛题思路资料…...

vue3与vue2的对比

Vue 3.0 和 Vue 2.0 是 Vue 前端框架的两个主要版本,它们有着不同的更新和优化: Vue 3.0 主要更新内容: 采用 TypeScript 作为开发语言,提高了代码的类型安全性。 速度更快,内存使用更少,支持大规模数据处…...

史上最全软件测试工程师常见的面试题总结(百度、oppo、中软国际、华为)备战金三银四

1、面试:神州数码1.介绍你下你项目中一个自动化实现的流程2.你觉得做自动化的意义在哪里 >需要对之前已经实现的功能进行回归测试、保证当前版本更新的内容不能影响到之前已经实现好的功能3.你们做自动化产生了什么结果 >测试报告、报错截图和报错日志、测试报…...

“深度学习”学习日记。卷积神经网络--用CNN的实现MINIST识别任务

2023.2.11 通过已经实现的卷积层和池化层,搭建CNN去实现MNIST数据集的识别任务; 一,简单CNN的网络构成: 代码需要在有网络的情况下运行,因为会下载MINIST数据集,运行后会生成params.pkl保留训练权重&…...

JavaWeb--JDBC练习

JDBC练习5.1 需求5.2 案例实现5.2.1 环境准备5.2.2 查询所有5.2.3 添加数据5.2.4 修改数据5.2.5 删除数据5.1 需求 完成商品品牌数据的增删改查操作 查询:查询所有数据添加:添加品牌修改:根据id修改删除:根据id删除 5.2 案例实…...

【LeetCode】2335. 装满杯子需要的最短总时长

2335. 装满杯子需要的最短总时长 题目描述 现有一台饮水机,可以制备冷水、温水和热水。每秒钟,可以装满 2 杯 不同 类型的水或者 1 杯任意类型的水。 给你一个下标从 0 开始、长度为 3 的整数数组 amount ,其中 amount[0]、amount[1] 和 a…...

Android 12.0 通过驱动实现禁用usb鼠标和usb键盘功能

1.1概述 在12.0的系统产品定制化开发中,在进行定制中有关于usb键盘和usb鼠标的需求中,产品要求禁止usb口挂载usb鼠标和usb键盘,所以需要要求在usb挂载类型的时候 判断如果是usb鼠标和usb键盘就不让挂载,这就需要从驱动方面入手来解决这个问题,接下来看下驱动的某些挂载usb…...

C++入门——内存管理

C入门——内存管理 C/C内存分布 分类是为了更好的管理 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char* pChar3 "abcd";int* ptr1 (…...

MySQL-InnoDB行格式浅析

简介 我们知道读写磁盘的速度非常慢,和内存读写差了几个数量级,所以当我们想从表中获取某些记录时, InnoDB 存储引擎需要一条一条的把记录从磁盘上读出来么? 不,那样会慢死,InnoDB 采取的方式是&#xff1a…...

AXI 总线协议学习笔记(4)

引言 前面两篇博文从简单介绍的角度说明了 AXI协议规范。 AXI 总线协议学习笔记(2) AXI 总线协议学习笔记(3) 从本篇开始,详细翻译并学习AXI协议的官方发布规范。 文档中的时序图说明: AXI指&#xff1…...

C++复习笔记6

1.String类的实现 注意深浅拷贝&#xff0c; C语言字符串拼接函数strcat() #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vld.h> #include<assert.h> using namespace std;class String {friend ostream& operator<<(ostream &am…...

指针的步长及意义(C语言基础)

指针的步长及意义 文章目录指针的步长及意义指针变量1后偏移的字节数不同指针解引用时取出的字节数不同其他例子不同类型的指针有何不同的意义指针变量1后跳跃字节数量不同解引用的时候&#xff0c;取出字节数量不同 指针变量1后偏移的字节数不同 代码演示&#xff1a;&#…...

SpringMVC:统一异常处理(11)

统一异常处理1. 说明2. 问题描述3. 异常处理器使用3.1 创建异常处理器类3.2 让程序抛出异常3.3 测试4. 项目异常处理方案4.1 异常分类4.2 异常解决方案4.3 异常解决方案的具体实现4.4 测试5. 总结1. 说明 \quad本篇文章是在文章SpringMVC&#xff1a;SSM整合&#xff08;Spring…...

SpringBoot的配置与使用

SpringBoot简介 我们的Spring是包含了众多工具的IoC容器&#xff0c;而SpringBoot则是Spring的加强版&#xff0c;可以更加方便快捷的使用 如果Spring是手动挡的车&#xff0c;那么SpringBoot就是自动挡的车&#xff0c;让我们的驾驶体验变得更好 SpringBoot具有一下几种特征…...

【Python】tkinter messagebox练习笔记

我一好友在朋友圈看到人家用代码花式秀恩爱&#xff0c;让我也做一个&#xff0c;我就用我学习半年python的功力&#xff0c;做了这一个东西。&#x1f64f;窗口主页面&#xff08;图一&#xff09;为了让我这个盆友有颜面&#xff0c;特意做了一个问答问他帅不帅&#xff0c;以…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

第22节 Node.js JXcore 打包

Node.js是一个开放源代码、跨平台的、用于服务器端和网络应用的运行环境。 JXcore是一个支持多线程的 Node.js 发行版本&#xff0c;基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。 本文主要介绍JXcore的打包功能。 JXcore 安装 下载JXcore安装包&a…...