数据结构和算法
文章平均质量分 92
数据结构和算法息息相关,所以放在一个专栏里面
zhonguncle
居高才能临下,深入才能浅出(这话是谁说的呢?肯定不是鲁迅)
展开
-
「动态规划」2/n:通过具体问题练习动态规划(爬楼梯问题、小偷问题)
在上一篇文章中提到的最经典的斐波那契数列就是一种一维的动态规划。一维其实也很容易看出来,只有一个属性(面上来说就是数字)相关。除了斐波那契数列之外,还有一些很常见或经典的一维动态规划问题,本文将通过其中的一些问题进一步介绍动态规划。爬楼梯问题问题描述给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。原创 2024-11-05 17:55:12 · 794 阅读 · 0 评论 -
IEEE 754浮点数构成与转换
IEEE 754 标准是现在主流的浮点数标准,除了常见语言中的 FP32、FP64 之类的类型,还有一些为了量化、加速深度学习的 FP8 类型(E4M3、E5M2)也是使用 IEEE 754 标准来定义无穷等含义。此外,通过了解和学习,在研究其他浮点数格式的时候也会有帮助,比如机器学习使用的 BFLOAT16。下图是 FP32、FP16、BF16 三种浮点格式对比(图自本文主要以 IEEE 754 的 FP32 为例,展示结构和如何得到浮点数。原创 2024-07-18 13:33:38 · 1358 阅读 · 0 评论 -
「动态规划」1/n:什么是动态规划?
在学习动态规划之前需要了解清楚什么叫做动态规划。很多教材直接讲内容了,并没有介绍其思想。动态规划(Dynamic Programming,缩写 DP)是一种编程范式,并非一种具体的算法。动态规划就是把一个大问题通过递归的方法划分成多个小问题,用数学方式来表达的话,就是一个多项式。这样可以在代码量变化不大的情况下解决不同规模的问题(实现这点正是递归)。这里多说一点:分而治之(Divide and Conquer,缩写 D&C)也是把一个大问题划分成小问题,但是分而治之是直接拆分的,而动态规划是递归拆分原创 2024-10-31 04:30:52 · 545 阅读 · 0 评论 -
如何计算UDP校验和
在了解 UDP 校验和的时候,发现资料很少,如果看教材的话,一定看到过下面这两张图,但是又看不懂,加上解释之后也难懂:本文先说具体怎么算的,再说一些细节,过程中顺带解释一下这两个图(第一张图是布局情况,第二张图是解释如何计算的)。原创 2024-08-07 19:40:32 · 1252 阅读 · 0 评论 -
红黑树与平衡二叉树的相同之处与不同之处
红黑树很多资料上写的非常繁杂,初次接触真的难以理解。写本文也就是为了记录一些思考和想法,并不会记录如何使用代码实现。不记录代码还有个原因:黑红树的算法就是根据各种情况进行一些操作,情况很复杂,分插入的和删除的,有的是资料记录这些,但是为什么要进行这些操作,为什么这些操作那么像但又略有不同却没多少人说明清楚。所以本文主要是记录想法的。原创 2024-08-03 17:52:58 · 767 阅读 · 0 评论 -
关键路径算法(Critical Path)
这个算法《算法导论》中并没有提及,很多书和博客说的有点奇怪,所以写本文作为笔记。关键路径是什么关键路径的定义非常简单:就是一个图中,权值之和最大的路径就是关键路径。为什么有关键路径关键路径的来源和拓扑排序是一样的,都是将一项较大的工程划分为多个子工程,然后表示子工程之间的关系的。关键路径和拓扑排序不同之处在于:拓扑排序强调子工程之间的先后顺序(说依赖关系可能更恰当一些),比如必须做完a才能做c。关键路径在拓扑排序的基础上,还加入了时间关系。这个时间关系不光是子工程之间的,也包括子工程和整体原创 2024-07-29 03:07:53 · 1993 阅读 · 0 评论 -
Hamming码是什么?如何计算和使用?
汉明码是什么在原始论文中,Hamming 阐述了一种检查和纠错编码:系统性代码(Systematic Code)。系统性代码的结构是:假设二进制位数为n,其中m位用于表示数据,k位用来检错和纠错。这就产生了一个冗余率R=n/m,使用这个冗余率R来作为传递相同信息的最小必要数。当时可能是信道容量真的不足,Hamming 在文章开头多次强调检查和纠正错误会降低信道的利用率。论文中构建了三种最小冗余的码:单个错误检测码(奇偶校验码);单个错误纠正码;单个错误纠正和双错误检测码。后两个都称为汉原创 2024-07-22 22:57:24 · 1012 阅读 · 3 评论 -
「字符串匹配算法 3/3」KMP (Knuth–Morris–Pratt)字符串匹配算法
在学习 KMP 的时候,我发现在国内的教材上是按照朴素算法的改进来介绍的,说是增加了next数组(部分匹配表,PM),这个表记录了子串中每个位置的最大相等前后缀的长度。这个介绍我不知道你有没有看懂这种介绍,我反正没看懂。然后我发现《算法导论》思路是按照有限自动机的改进来介绍的,也提到了求前缀,而且数学性极强。懂了点思路,但是对代码怎么写毫无头绪。这两个给的解释不能让我满意。网上的博客和代码要么就是参考国内教材给解释,要么就是参考算法导论给解释,要么没解释,所以结果也是一样。原创 2024-07-14 00:03:00 · 619 阅读 · 0 评论 -
「字符串匹配算法 2/3」有限自动机匹配字符串算法
有限自动机匹配字符串算法需要一定的数论知识,而且也不是很好玩。本文不会展开说其数学属性,因为要说清楚这点需要读者有一定的离散数学基础,不然就得先解释清楚一些概念。所以如果你不懂自动机、状态机等概念,对集合、关系等概念不熟悉,也不想搞懂,那么理解下面的代码就行了,概念上我会进行一些解释,毕竟也是个记录。如果你想搞懂背后的数学属性,首先学一下离散数学,重点是数论。有基础之后,就可以看一下《算法导论》和芝加哥大学的,后者示例更好一些。原创 2024-07-12 20:26:28 · 920 阅读 · 0 评论 -
「字符串匹配算法 1/3」朴素和Rabin-Karp
字符串匹配算法一直是我的一大短板,刚好这段时间有需要,借此机会就好好补补。匹配算法主要是从一段内容中匹配某一部分(pattern,这个词有时候也被翻译成模式,所以有时候也叫模式匹配),比如文本编辑器中查找某个单词、DNA 序列中查找特定序列。。朴素匹配算法没有预处理。下面是《算法导论》中列出的四种匹配算法,我就先学会这四种好了。当然还有更多的算法,不过一开始容易贪多嚼不烂。0O((n−m1mΘmO((n−m1mΘm∣∑∣ΘnΘmΘn上面表格中的。原创 2024-07-12 20:18:18 · 816 阅读 · 0 评论 -
树选择排序(Tree Selection Sorting)介绍
或许你有一个疑问:为什么堆排序使用二叉树,但是叫堆排序,而不是树排序?因为堆排序的前身正是叫做树选择排序(Tree Selection Sorting),使用树结构,但是要稍微简单一些。高德纳(Donald E. Knuth)先生形容树选择排序算法像兵乓球比赛,所以这里使用一下 TAOCP 中的例子。假设有八个人参加比赛,需要评判出第一名到第八名,赛程如下:Kim 和 Sandy、Chris 和 Lou、Pat 和 Ray、Dale 和 Robin分组比赛,胜者晋级。可以看到在 7 次比赛之后,最后的冠原创 2022-12-06 08:56:20 · 627 阅读 · 0 评论 -
快速排序(QuickSort)方法的历史、代码、测试,以及Hoare-Partition和Lomuto-Partition的区别(还有很多其他快速排序算法)
在学习快速排序的时候,发现很多人说的快速排序方法不一样(比如教材和网上说到的快速排序过程不一样),很好奇是为什么,而且开发、考试等很多场景都需要用到。就去翻阅了一下《算法导论》想搞明白,发现这种情况的原因和快速排序的发展史有关。于是就查阅了很多资料,来写下本文作为记录。原创 2022-10-04 09:07:20 · 2270 阅读 · 0 评论 -
数据结构中,索引存储和散列存储区别较为详细的介绍
数据结构中有两种存储结构很容易搞混,那就是索引存储结构和散列存储结构(哈希存储结构)。索引存储:根据地址就可以找到对应的关键字。可以理解成一个黄页,你根据一个人的名字,就可以找到他的电话。散列存储:名字中的“散列”就是常听到的 hash(哈希值),hash 是通过一种算法来运算出来的,比如 MD5。在这种存储格式下,地址会通过 hash 算法来运算成一个相同长度的 hash 值,然后存放这个 hash 值,而不是直接存放地址。在访问关键字的时候会通过运算解码 hash 值,然后再访问。这个时候,节原创 2022-09-03 14:35:53 · 7504 阅读 · 0 评论 -
C/C++ 如何实现和使用链表(linked list)
由于实现链表(Linked List)是实现一种数据结构,使用结构体(structure),而不是必须使用 Class。所以 C 和 C++ 没区别。原创 2022-08-17 21:58:38 · 1123 阅读 · 0 评论
分享