【博主力荐】《Hello 算法》动画图解、一键运行的数据结构与算法教程
无论你是小白还是“大神”,数据结构对于我们码农都是十分重要的,一个内容优质、有趣、便捷的算法学习网站对我们都是至关重要的,Hello算法是具备这些的,本文无商业用途,仅分享,若感兴趣也可以去GitHub star一下作者~
📖引言
本文介绍一个GitHub热门项目-Hello 算法(全文若引用书中的案例或段落,仅用于读者理解,方便阅读,分享为主,文章结尾附上相关链接)
本书旨在通过清晰易懂的动画图解和可运行的代码示例,使读者理解算法和数据结构的核心概念,并能够通过编程来实现它们。在此基础上,本书致力于揭示算法在复杂世界中的生动体现,展现算法之美。希望本书能够帮助到你!
📖关于本书
本项目旨在创建一本开源、免费、对新手友好的数据结构与算法入门教程。
-
全书采用动画图解,内容清晰易懂、学习曲线平滑,引导初学者探索数据结构与算法的知识地图。
-
源代码可一键运行,帮助读者在练习中提升编程技能,了解算法工作原理和数据结构底层实现。
-
提倡读者互助学习,欢迎大家在评论区提出问题与分享见解,在交流讨论中共同进步。
-
复杂度分析:数据结构和算法的评价维度与方法。时间复杂度和空间复杂度的推算方法、常见类型、示例等。
-
数据结构:基本数据类型和数据结构的分类方法。数组、链表、栈、队列、哈希表、树、堆、图等数据结构的定义、优缺点、常用操作、常见类型、典型应用、实现方法等。
-
算法:搜索、排序、分治、回溯、动态规划、贪心等算法的定义、优缺点、效率、应用场景、解题步骤和示例问题等。
📖如何使用本书
- 标题后标注 * 的是选读章节,内容相对困难。如果你的时间有限,可以先跳过。
- 专业术语会使用黑体(纸质版和 PDF 版)或添加下划线(网页版),例如数组(array)。建议记住它们,以便阅读文献。
- 重点内容和总结性语句会 加粗,这类文字值得特别关注。
- 有特指含义的词句会使用“引号”标注,以避免歧义。
- 当涉及编程语言之间不一致的名词时,本书均以 Python 为准,例如使用 None 来表示“空”。
- 本书部分放弃了编程语言的注释规范,以换取更加紧凑的内容排版。注释主要分为三种类型:标题注释、内容注释、多行注释。
在动画图解中高效学习
相较于文字,视频和图片具有更高的信息密度和结构化程度,更易于理解。在本书中,重点和难点知识将主要通过动画以图解形式展示,而文字则作为解释与补充。
如果你在阅读本书时,发现某段内容提供了如图 0-2 所示的动画图解,请以图为主、以文字为辅,综合两者来理解内容。
在代码实践中加深理解
本书的配套代码托管在 GitHub 仓库。源代码附有测试样例,可一键运行。
如果时间允许,建议你参照代码自行敲一遍。如果学习时间有限,请至少通读并运行所有代码。
与阅读代码相比,编写代码的过程往往能带来更多收获。动手学,才是真的学。
运行代码的前置工作主要分为三步。
第一步:安装本地编程环境。请参照附录所示的教程进行安装,如果已安装,则可跳过此步骤。
第二步:克隆或下载代码仓库。前往 GitHub 仓库。如果已经安装 Git ,可以通过以下命令克隆本仓库:
git clone https://github.com/krahets/hello-algo.git
当然,你也可以在图 0-4 所示的位置,点击“Download ZIP”按钮直接下载代码压缩包,然后在本地解压即可。
第三步:运行源代码。如图 0-5 所示,对于顶部标有文件名称的代码块,我们可以在仓库的 codes 文件夹内找到对应的源代码文件。源代码文件可一键运行,将帮助你节省不必要的调试时间,让你能够专注于学习内容。
除了本地运行代码,网页版还支持 Python 代码的可视化运行(基于 pythontutor 实现)。如图 0-6 所示,你可以点击代码块下方的“可视化运行”来展开视图,观察算法代码的执行过程;也可以点击“全屏观看”,以获得更好的阅览体验。
📖算法学习路线
从总体上看,我们可以将学习数据结构与算法的过程划分为三个阶段。
- 阶段一:算法入门。我们需要熟悉各种数据结构的特点和用法,学习不同算法的原理、流程、用途和效率等方面的内容。
- 阶段二:刷算法题。建议从热门题目开刷,先积累至少 100 道题目,熟悉主流的算法问题。初次刷题时,“知识遗忘”可能是一个挑战,但请放心,这是很正常的。我们可以按照“艾宾浩斯遗忘曲线”来复习题目,通常在进行 3~5 轮的重复后,就能将其牢记在心。推荐的题单和刷题计划请见此 GitHub 仓库。
- 阶段三:搭建知识体系。在学习方面,我们可以阅读算法专栏文章、解题框架和算法教材,以不断丰富知识体系。在刷题方面,可以尝试采用进阶刷题策略,如按专题分类、一题多解、一解多题等,相关的刷题心得可以在各个社区找到。
如图 0-8 所示,本书内容主要涵盖“阶段一”,旨在帮助你更高效地展开阶段二和阶段三的学习。
📖Hello算法内容分享
下面我给大家分享书中有关栈的相关内容
📖栈
栈(stack)是一种遵循先入后出逻辑的线性数据结构。
我们可以将栈类比为桌面上的一摞盘子,如果想取出底部的盘子,则需要先将上面的盘子依次移走。我们将盘子替换为各种类型的元素(如整数、字符、对象等),就得到了栈这种数据结构。
如图 5-1 所示,我们把堆叠元素的顶部称为“栈顶”,底部称为“栈底”。将把元素添加到栈顶的操作叫作“入栈”,删除栈顶元素的操作叫作“出栈”。
书中也列出了一些栈的常用操作
# 初始化栈
# Python 没有内置的栈类,可以把 list 当作栈来使用
stack: list[int] = []
# 元素入栈
stack.append(1)
stack.append(3)
stack.append(2)
stack.append(5)
stack.append(4)
# 访问栈顶元素
peek: int = stack[-1]
# 元素出栈
pop: int = stack.pop()
# 获取栈的长度
size: int = len(stack)
# 判断是否为空
is_empty: bool = len(stack) == 0
对于栈的实现,书中使用两种方式,基于链表的实现、基于数组的实现
书中不光有动画演示
还有多种语言,如下图
同时还包含可视化运行,这里点击全屏显示,更大更好的可以看到代码的运行
基于数组的实现书中介绍的形式和上面类似,这里不做过多的解释
📖两种实现对比
支持操作
两种实现都支持栈定义中的各项操作。数组实现额外支持随机访问,但这已超出了栈的定义范畴,因此一般不会用到。
时间效率
在基于数组的实现中,入栈和出栈操作都在预先分配好的连续内存中进行,具有很好的缓存本地性,因此效率较高。然而,如果入栈时超出数组容量,会触发扩容机制,导致该次入栈操作的时间复杂度变为 。
在基于链表的实现中,链表的扩容非常灵活,不存在上述数组扩容时效率降低的问题。但是,入栈操作需要初始化节点对象并修改指针,因此效率相对较低。不过,如果入栈元素本身就是节点对象,那么可以省去初始化步骤,从而提高效率。
综上所述,当入栈与出栈操作的元素是基本数据类型时,例如 int 或 double ,我们可以得出以下结论。
基于数组实现的栈在触发扩容时效率会降低,但由于扩容是低频操作,因此平均效率更高。
基于链表实现的栈可以提供更加稳定的效率表现。
空间效率
在初始化列表时,系统会为列表分配“初始容量”,该容量可能超出实际需求;并且,扩容机制通常是按照特定倍率(例如 2 倍)进行扩容的,扩容后的容量也可能超出实际需求。因此,基于数组实现的栈可能造成一定的空间浪费。
然而,由于链表节点需要额外存储指针,因此链表节点占用的空间相对较大。
综上,我们不能简单地确定哪种实现更加节省内存,需要针对具体情况进行分析。
栈的典型应用
这里作者还贴心的为我们展示了一些应用方便我们进行联想
浏览器中的后退与前进、软件中的撤销与反撤销。每当我们打开新的网页,浏览器就会对上一个网页执行入栈,这样我们就可以通过后退操作回到上一个网页。后退操作实际上是在执行出栈。如果要同时支持后退和前进,那么需要两个栈来配合实现。
程序内存管理。每次调用函数时,系统都会在栈顶添加一个栈帧,用于记录函数的上下文信息。在递归函数中,向下递推阶段会不断执行入栈操作,而向上回溯阶段则会不断执行出栈操作。
📖相关链接
Hello,算法在线阅读:https://www.hello-algo.com/
PDF:https://github.com/krahets/hello-algo/releases
hello-algo GitHub:https://github.com/krahets/hello-algo
代码仓库:https://github.com/krahets/hello-algo/tree/main/codes
📖结语
无论你是小白还是“大神”,数据结构对于我们码农都是十分重要的,一个内容优质、有趣、便捷的算法学习网站对我们都是至关重要的,Hello算法是具备这些的,本文无商业用途,仅分享,若感兴趣也可以去GitHub star一下作者~
更多推荐
所有评论(0)