《数据结构与算法之美》读书笔记
文章平均质量分 84
本书分为11章。第1章介绍复杂度分析方法。第2章介绍数组、链表、栈和队列这些基础的线性表数据结构。第3章介绍递归编程技巧、8种经典排序、二分查找及二分查找的变体问题。第4章介绍哈希表、位图、哈希算法和布隆过滤器。第5章介绍树相关的数据结构,包括二叉树、二叉查找树、平衡二叉查找树、递归树和B+树。第6
Chiang木
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
数据结构与算法之美【19】-字符串匹配
字符串匹配这样一个功能,我想对于任何一个开发工程师来说,应该都不会陌生。我们用的最多的就是编程语言提供的字符串查找函数,比如 Java 中的 indexOf(),Python 中的 find() 函数等,它们底层就是依赖接下来要讲的字符串匹配算法。1、BF 算法BF 算法中的 BF 是 Brute Force 的缩写,中文叫作暴力匹配算法,也叫朴素匹配算法。从名字可以看出,这种算法的字符串匹配方式很“暴力”,当然也就会比较简单、好懂,但相应的性能也不高。在开始讲解这个算法之前,我先定义两个概念:原创 2022-03-14 18:25:28 · 1124 阅读 · 0 评论 -
数据结构与算法之美【18】-深度和广度优先搜索
我们知道,算法是作用于具体数据结构之上的,深度优先搜索算法和广度优先搜索算法都是基于“图”这种数据结构的。这是因为,图这种数据结构的表达能力很强,大部分涉及搜索的场景都可以抽象成“图”。我们上一节讲过,图有两种主要存储方法,邻接表和邻接矩阵。需要说明一下,深度优先搜索算法和广度优先搜索算法,既可以用在无向图,也可以用在有向图上。1、广度优先搜索(BFS)广度优先搜索(Breadth-First-Search),我们平常都简称 BFS。直观地讲,它其实就是一种“地毯式”层层推进的搜索策略,即先查找原创 2022-03-14 17:33:51 · 667 阅读 · 0 评论 -
数据结构与算法之美【17】-图
目录图的基本概念图的存储邻接矩阵存储邻接表存储图的基本概念图大概分为3种:无向图、有向图、带权图,图中的元素我们就叫做顶点(vertex),从我画的图中可以看出来,图中的一个顶点可以与任意其他顶点建立连接关系。我们把这种建立的关系叫做边(edge)。而顶点的度(degree),其实就是跟顶点相连接的边的条数。顶点的入度指的是有多少条边指向这个顶点;顶点的出度则表示有多少条边是以这个顶点为起点指向其他顶点。图的存储邻接矩阵存储邻接矩阵(Adjacency Matri..原创 2021-04-23 23:46:08 · 427 阅读 · 0 评论 -
数据结构与算法之美【16】-堆
目录堆的定义堆的插入操作堆的删除操作建堆堆排序堆的定义堆是一种特殊的树,它满足这两点要求:堆是一个完全二叉树,即除了最后一层,其他层的节点个数都是满的,最后一层的节点都靠左排列。; 堆中每个节点的值都大于等于(或者小于等于)其左右子节点的值对于每个节点的值都大于等于子树中每个节点值的堆,我们叫做“大顶堆”。对于每个节点的值都小于等于子树中每个节点值的堆,我们叫做“小顶堆”。堆的插入操作在堆的插入过程中,我们让新插入的节点与父节点比较大小,如果不满足子节点..原创 2021-04-23 23:14:33 · 2973 阅读 · 0 评论 -
数据结构与算法之美【15】-二叉查找树
二叉查找树也叫二叉搜索树。二叉查找树要求,在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值。中序遍历二叉查找树,可以输出有序的数据序列,时间复杂度是 O(n),非常高效。我画了几个二叉查找树的例子,你一看应该就清楚了:目录二叉查找树的查找操作二叉查找树的插入操作二叉查找树的删除操作存在重复数据的二叉查找树二叉查找树的查找操作二叉查找树中查找逻辑很简单:先取根节点的值,如果它等于我们要查找的值,那就返回。如果要查找..原创 2021-03-25 23:49:26 · 3197 阅读 · 0 评论 -
数据结构与算法之美【14】-二叉树基础
在开始之前先将几个关于树结构的基本概念:我们继续来认识两种比较特殊的树:编号 2 的二叉树的叶子节点全都在最底层,除了叶子节点之外,每个节点都有左右两个子节点,这种二叉树就叫做满二叉树。编号 3 的二叉树中,叶子节点都在最底下两层,最后一层的叶子节点都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大,这种二叉树叫做完全二叉树。...原创 2021-03-25 23:03:59 · 2912 阅读 · 0 评论 -
数据结构与算法之美【13】-哈希算法
目录哈希算法的定义及要求哈希算法的应用安全加密唯一标识数据校验散列函数负载均衡数据分片分布式存储哈希算法的定义及要求哈希算法的定义:将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制值串就是哈希值。一个优秀的哈希算法需要满足的以下几点要求:从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法); 对输入数据非常敏感,哪怕原始数据只修改了一个 Bit,最后得到的哈希值也大不相同; ..原创 2021-03-24 22:33:31 · 530 阅读 · 0 评论 -
数据结构与算法之美【12】-散列表
散列思想散列表的英文叫“Hash Table”,我们平时也叫它“哈希表”或者“Hash 表”。散列表用的是数组支持按照下标随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来。例如学校运动会,选手的参赛编号不能简单的设置为整型数字,而是要加上年级、班级这些更详细的信息,所以我们把编号的规则稍微修改了一下,用 6 位数字来表示。比如 051167,其中,前两位 05 表示年级,中间两位 11 表示班级,最后两位还是原来的编号 1 到 89。这个时候我们该如何存储选手信息,才能够支持..原创 2021-03-23 23:08:31 · 1822 阅读 · 0 评论 -
数据结构与算法之美【11】-跳表
目录什么是跳表跳表的内存问题跳表的复杂度分析跳表索引动态更新什么是跳表我们知道链表这种结构,虽然他的插入和删除的时间复杂度很高,只有O(1),但是它的查找却很慢,为O(n)。例如我们要查找一个元素,不得不编译一下连边才能找到:但是如果我们像下图中那样,对链表建立一级“索引”,即每两个结点提取一个结点到上一级,我们把抽出来的那一级叫做索引或索引层,索引层有个next指针指向索引在链表中位置:当然这只是一级索引,如果数据量庞大,我们可以建立两级、三级,甚至十级索引..原创 2021-03-22 23:59:03 · 354 阅读 · 0 评论 -
数据结构与算法之美【10】-二分查找
二分查找针对的是一个有序的数据集合,查找思想有点类似分治思想。每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。它的时间复杂度也是 O(logn)。二分分查找应用场景的局限性:二分查找依赖的是顺序表结构,简单点说就是数组。 二分查找针对的是有序数据。 数据量太小不适合二分查找,可以直接遍历数组。 数据量太大也不适合二分查找,因为其底层需要依赖数组这种数据结构目录二分查找的变体变体一:查找第一个值等于给定值的元素变体二...原创 2021-03-18 23:19:09 · 637 阅读 · 0 评论 -
数据结构与算法之美【9】-排序
在开始介绍几种排序算法之前,先介绍几种排序相关的概念,防止后面介绍时,有理解偏差:稳定性:如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变,则说这种排序是稳定的,否则就是不稳定的。 原地排序:指的是在排序过程中不申请多余的存储空间或者申请很少的空间,只利用原来存储待排数据的存储空间进行比较和交换的数据排序 有序度:指的是待排序的序列a中,满足i < j且a[i] <= a[j]要求的元素对的个数。 满有序度:指的是待排序的序列a中,所有元素对都满足...原创 2021-03-13 17:30:07 · 361 阅读 · 0 评论 -
数据结构与算法之美【8】-递归算法
递归严格说起来不算一种算法,只能说是一种问题处理思想或者问题处理技巧。只要问题同时满足以下三个条件,就可以考虑用递归来解决:1. 一个问题的解可以分解为几个子问题的解 2. 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样 3. 存在递归终止条件个人觉得,写递归代码最关键的是写出递推公式,找到终止条件。下面举一个例子,然后一步一步实现一个递归代码,帮你理解递归思想:假如这里有 n 个台阶,每次你可以跨 1 个台阶或者 2 个台阶,请问走这 n 个台阶有多少种走法?解..原创 2021-03-13 15:14:14 · 229 阅读 · 0 评论 -
数据结构与算法之美【7】-队列
目录一、概述二、顺序队列三、链式队列三、循环队列四、示例代码一、概述队列跟栈非常相似,也是一种操作受限的线性表数据结构。跟栈一样,队列可以用数组来实现,也可以用链表来实现,用数组实现的队列叫作顺序队列,用链表实现的队列叫作链式队列。队列最基本的操作也是两个:入队 enqueue()(放一个数据到队列尾部)和出队 delqueue()(从队列头部取一个元素),所以队列需要两个指针:一个是 head 指针,指向队头,一个是 tail 指针,指向队尾。二、顺序队..原创 2021-03-13 14:40:00 · 495 阅读 · 1 评论 -
数据结构与算法之美【6】-栈
栈是一种操作受限的线性表,只允许从栈顶插入和删除数据,所以每次删除的元素都是最后进栈的元素,故栈也被称为后进先出(LIFO)表。栈主要包含两个操作,入栈(也叫做压栈)和出栈,即在栈顶插入数据和从栈顶删除数据。实际上,栈既可以用数组来实现,也可以用链表来实现。用数组实现的栈,我们叫作顺序栈,用链表实现的栈,我们叫作链式栈。关于时间复杂度,因为在出栈只需要移动一个变量存储空间,所以它的时间复杂度为O(1),但是对于入栈分两种情况:(1)栈空间固定不变此时若空间不满,则直接入栈,如空间满,则丢..原创 2021-03-13 00:14:12 · 687 阅读 · 0 评论 -
数据结构与算法之美【5】-链表
关于链表,首先我们要了解它和数组的一个最大区别:数组需要一块连续的内存空间来存储,而链表恰恰相反,它通过“指针”将一组零散的内存块串联起来使用。代码实现可以参考这篇文章:代码示例关于链表的时间复杂度,因为在对链表执行插入和删除操作时无需保持内存数据的连续性,而仅仅是修改一下指定节点的next指针指向,所以对应的时间复杂度是 O(1),但是因为不支持随机访问,只能通过节点的next指针进行遍历,所以随机访问的时间复杂度是O(n)。链表结构五花八门,今天重点介绍四种最常见的链表结构:单链表、双向..原创 2021-03-12 23:35:34 · 573 阅读 · 0 评论 -
数据结构与算法之美【4】-数组
数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。在面试的时候,面试官常常会问数组和链表的区别,很多人都回答说,“链表适合插入、删除,时间复杂度 O(1);数组适合查找,查找时间复杂度为 O(1)”。实际上,这种表述是不准确的。数组是适合查找操作,但是查找的时间复杂度并不为 O(1)。即便是排好序的数组,你用二分查找,时间复杂度也是 O(logn)。所以,正确的表述应该是,数组支持随机访问,根据下标随机访问的时间复杂度为 O(1)。插入操作假设数组的...原创 2021-03-12 08:43:47 · 368 阅读 · 0 评论 -
数据结构与算法之美【3】-复杂度分析(下)
今天我会继续给你讲四个复杂度分析方面的知识点,最好情况时间复杂度(best case time complexity)、最坏情况时间复杂度(worst case time complexity)、平均情况时间复杂度(average case time complexity)、均摊时间复杂度(amortized time complexity)。如果这几个概念你都能掌握,那对你来说,复杂度分析这部分内容就没什么大问题了。一、最好、最坏情况时间复杂度首先我们来看一个稍微复杂的例子,你可以用我上节教...原创 2021-03-12 00:13:09 · 449 阅读 · 0 评论 -
数据结构与算法之美【2】-复杂度分析(上)
相对于复杂度分析,还有一个对立的分析方法,叫做事后统计法,但它有两个缺点:测试结果非常依赖测试环境 测试结果受数据规模的影响很大我们需要一个不用具体的测试数据来测试,就可以粗略地估计算法的执行效率的方法。这就是我们今天要讲的时间、空间复杂度分析方法。一、大 O 复杂度表示法对于大O复杂度表示法,我们可以把它总结成一个公式:其中,T(n) 表示代码执行的时间,即我们平时所说的时间复杂度;n 表示数据规模的大小;f(n) 表示每行代码执行的次数总和。公式中的 O,表示代码的执行时间 ..原创 2021-03-11 23:22:59 · 381 阅读 · 0 评论 -
数据结构与算法之美【1】-数据结构与算法简介
什么是数据结构?什么是算法?从广义上讲,数据结构就是指一组数据的存储结构。算法就是操作数据的一组方法。从狭义上讲,也就是我们专栏要讲的,是指某些著名的数据结构和算法,比如队列、栈、堆、二分查找、动态规划等。那数据结构和算法有什么关系呢?为什么大部分书都把这两个东西放到一块儿来讲呢?这是因为,数据结构和算法是相辅相成的。数据结构是为算法服务的,算法要作用在特定的数据结构之上。 因此,我们无法孤立数据结构来讲算法,也无法孤立算法来讲数据结构。为了让你对数据结构和算法能有个全面的认识,我画了一原创 2021-03-10 22:56:54 · 554 阅读 · 0 评论
分享