随笔分类 -  数据结构与算法之美专栏学习笔记

摘要:BF (Brute Force) 暴力/朴素匹配算法 主串和模式串 我们在字符串 A 中查找字符串 B,那字符串 A 就是主串,字符串 B 就是模式串。 我们把主串的长度记作 n,模式串的长度记作 m。因为我们是在主串中查找模式串,所以 n>m。 BF算法思想 在主串中,检查起始位置分别是 0、1、 阅读全文
posted @ 2018-12-24 14:10 TKhaos 阅读(404) 评论(0) 推荐(0)
摘要:图的概念 树中的元素称为节点,图中的元素称为作顶点Vertex。 图中的一个顶点可以与任意其他顶点建立连接关系,这种建立的关系叫作边Edge。 跟顶点相连接的边的条数叫作顶点的度Degree。 边有方向的图叫作有向图,边没有方向的图就叫作无向图。 无向图中度表示一个顶点有多少条边,在有向图中,把度分 阅读全文
posted @ 2018-12-04 20:39 TKhaos 阅读(633) 评论(0) 推荐(0)
摘要:堆的应用一:优先级队列 优先级队列首先应该是一个队列。队列最大的特性就是先进先出。但是在优先级队列中,出队顺序不是先进先出,而是按照优先级来,优先级最高的,最先出队。 用堆来实现优先级队列是最直接、最高效的。这是因为,堆和优先级队列非常相似。一个堆就可以看作一个优先级队列。很多时候,它们只是概念上的 阅读全文
posted @ 2018-12-02 19:30 TKhaos 阅读(467) 评论(0) 推荐(0)
摘要:堆和堆排序 如何理解堆 堆是一种特殊的树,只要满足以下两点,这个树就是一个堆。 ①完全二叉树,完全二叉树要求除了最后一层,其他层的节点个数都是满的,最后一层的节点都靠左排列。 ②树中每一个结点的值都必须大于等于(或小于等于)其子树中每个节点的值。大于等于的情况称为大顶堆,小于等于的情况称为小顶堆。 阅读全文
posted @ 2018-12-02 18:01 TKhaos 阅读(320) 评论(0) 推荐(0)
摘要:二叉查找树 Binary Search Tree 二叉查找树的定义 二叉查找树又称二叉搜索树。其要求在二叉树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树的节点的值都大于这个节点的值。 二叉查找树的查找操作 二叉树类、节点类以及查找方法的代码实现 先取根节点,如果它等于我 阅读全文
posted @ 2018-11-22 13:04 TKhaos 阅读(339) 评论(0) 推荐(0)
摘要:树 节点的定义 树中的元素称之为节点 高度的定义 节点的高度:节点到叶子节点的最长路径 树的高度:跟节点的高度 深度的定义 根节点到这个节点所经历的边的个数 层的定义 节点的深度+1 二叉树 满二叉树 除了叶子结点外每个节点都有左右两个子节点 完全二叉树 叶子结点都在最低下两层,最后一层的叶子节点都 阅读全文
posted @ 2018-11-13 19:19 TKhaos 阅读(280) 评论(0) 推荐(0)
摘要:哈希算法的定义和原理 将任意长度的二进制串映射为固定长度的二进制串。 这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制串就是哈希值。 设计一个优秀的哈希算法需要满足: 从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法); 对输入数据非常敏感,哪怕原始数据只修改了一个 Bit 阅读全文
posted @ 2018-11-13 15:51 TKhaos 阅读(464) 评论(0) 推荐(0)
摘要:散列表和链表组合使用 LRU缓存淘汰算法 借助散列表,我们可以把LRU缓存淘汰算法的时间复杂度降为O(1)。 一个缓冲cache系统主要包含以下操作 往缓存中添加一个数据; 从缓存中删除一个数据; 在缓存中查找一个数据。 单纯采用链表,时间复杂度只能是O(n)。 将散列表和双向链表结合,就可以降为O 阅读全文
posted @ 2018-11-13 14:48 TKhaos 阅读(236) 评论(0) 推荐(0)
摘要:散列表碰撞攻击 在极端情况下,有些恶意的攻击者,还有可能通过精心构造的数据,使得所有的数据经过散列函数之后,都散列到同一个槽里。 如果我们使用的是基于链表的冲突解决方法,那这个时候,散列表就会退化为链表,查询的时间复杂度就从 O(1) 急剧退化为 O(n)。 如何设计一个可以应对各种异常情况的工业级 阅读全文
posted @ 2018-11-12 22:27 TKhaos 阅读(285) 评论(0) 推荐(0)
摘要:散列表 概述 散列表Hash Table来源于数组,它借助散列函数对数组这种数据结构进行扩展,利用的是数组支持按照下标随机访问元素的特性。 需要存储在散列表中的数据我们称为键key,将键转化为数组下标的方法hash(key)称为散列函数,散列函数的计算结果称为散列值。 将数据存储在散列值对应的数组下 阅读全文
posted @ 2018-11-12 21:05 TKhaos 阅读(698) 评论(1) 推荐(0)
摘要:跳表的概念 对链表建立n级索引,例如每两个结点提取一个节点到上一层,称之为索引层。 图中的down表示down指针,指向下一级结点 跳表的时间复杂度 跳表的高度 跳表的高度是log2n。 跳表的时间复杂度 跳表中查询某个数据的时间复杂度是O(logn)。 跳表的空间复杂度及优化 跳表的空间复杂度 跳 阅读全文
posted @ 2018-11-12 19:53 TKhaos 阅读(482) 评论(0) 推荐(0)
摘要:四种常见的二分查找变形问题 查找第一个值等于给定值的元素 查找最后一个值等于给定值的元素 查找第一个大于等于给定值的元素 查找最后一个小于等于给定值的元素 适用性分析 凡是能用二分查找解决的,绝大部分我们更倾向于用散列表或者二叉查找树, 即便二分查找在内存上更节省,但是毕竟内存如此紧缺的情况并不多。 阅读全文
posted @ 2018-11-12 18:56 TKhaos 阅读(219) 评论(0) 推荐(0)
摘要:二分查找概念 二分查找针对的是一个有序的数据集合,每次通过跟区间中间的元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间缩小为0。 时间复杂度 时间复杂度是O(logn)。 二分查找实现 循环实现 注意事项 循环退出条件是:start<=end,而不是start<end。 mi 阅读全文
posted @ 2018-11-11 20:04 TKhaos 阅读(361) 评论(0) 推荐(0)
摘要:选择合适的排序算法 回顾 选择排序算法的原则 1)线性排序时间复杂度很低但使用场景特殊,如果要写一个通用排序函数,不能选择线性排序。 2)为了兼顾任意规模数据的排序,一般会首选时间复杂度为O(nlogn)的排序算法来实现排序函数。 3)同为O(nlogn)的快排和归并排序相比,归并排序不是原地排序算 阅读全文
posted @ 2018-11-11 18:26 TKhaos 阅读(201) 评论(0) 推荐(0)
摘要:线性排序 线性排序的概念 线性排序算法包括桶排序、计数排序、基数排序。 线性排序算法的时间复杂度为O(n)。 线性排序的特点 此3种排序算法都不涉及元素之间的比较操作,是非基于比较的排序算法。 对排序数据的要求很苛刻,重点掌握此3种排序算法的适用场景。 桶排序 算法原理 1)将要排序的数据分到几个有 阅读全文
posted @ 2018-11-11 17:51 TKhaos 阅读(526) 评论(0) 推荐(0)
摘要:分治思想 分治思想 分治,顾明思意就是分而治之,将一个大问题分解成小的子问题来解决,小的子问题解决了,大问题也就解决了。 分治与递归的区别 分治算法一般都用递归来实现的。分治是一种解决问题的处理思想,递归是一种编程技巧。 归并排序 算法原理 归并的思想 先把数组从中间分成前后两部分,然后对前后两部分 阅读全文
posted @ 2018-11-11 12:15 TKhaos 阅读(255) 评论(0) 推荐(0)
摘要:排序方法 冒泡排序、插入排序、选择排序、快速排序、归并排序、计数排序、基数排序、桶排序。 复杂度归类 冒泡排序、插入排序、选择排序 O(n^2) 快速排序、归并排序 O(nlogn) 计数排序、基数排序、桶排序 O(n) 算法的执行效率 1. 最好、最坏、平均情况时间复杂度。 2. 时间复杂度的系数 阅读全文
posted @ 2018-11-01 19:34 TKhaos 阅读(243) 评论(0) 推荐(0)
摘要:什么是递归 递归的概念 递归是一种非常高效、简洁的编码技巧,一种应用非常广泛的算法, 比如DFS深度优先搜索、前中后序二叉树遍历等都是使用递归。 方法或函数调用自身的方式称为递归调用,调用称为递,返回称为归。 基本上,所有的递归问题都可以用递推公式来表示,比如 递归需要满足三个条件 1.一个问题的解 阅读全文
posted @ 2018-10-27 19:57 TKhaos 阅读(196) 评论(0) 推荐(0)
摘要:队列的概念 1.先进者先出,这就是典型的“队列”结构。 2.支持两个操作:入队enqueue(),放一个数据到队尾;出队dequeue(),从队头取一个元素。 3.所以,和栈一样,队列也是一种操作受限的线性表。 数组实现(顺序队列) 顺序队列的C#代码实现 以下代码实现了简单的顺序队列,队列初始化以 阅读全文
posted @ 2018-10-24 21:45 TKhaos 阅读(249) 评论(0) 推荐(0)
摘要:什么是栈 1.后进者先出,先进者后出,这就是典型的“栈”结构。 2.从栈的操作特性来看,是一种“操作受限”的线性表,只允许在端插入和删除数据。 为什么需要栈 1.栈是一种操作受限的数据结构,其操作特性用数组和链表均可实现。 2.但任何数据结构都是对特定应用场景的抽象,数组和链表虽然使用起来更加灵活, 阅读全文
posted @ 2018-10-16 17:11 TKhaos 阅读(300) 评论(0) 推荐(0)