数据结构与算法
无
含低调
一个梦想是成为教师的程序员
展开
-
21. 串(sequence)
1 串本课程研究的串是开发中非常熟悉的字符串,是由若干个字符组成的有限序列字符串 thank 的前缀(prefix)、真前缀(proper prefix)、后缀(suffix)、真后缀(proper suffix)真前缀就是不包括自身的所有前缀2 串匹配算法查找一个模式串(pattern)在文本串(text)中的位置,本文种用 tlen 代表文本串 text 的长度,plen 代表模式串 pattern 的长度几个经典的串匹配算法蛮力(Brute Force)KMPBoy原创 2020-05-26 11:26:57 · 284 阅读 · 0 评论 -
20. B+树
1. B+树B+树是B树的变体,常用于数据库和操作系统的文件系统中,MySQL数据库的索引就是基于B+树实现的B+树的特点分为内部节点(非叶子)、叶子节点2种节点内部节点只存储key,不存储具体数据(B树两者都存)叶子节点存储key和具体数据(图中的Q)所有的叶子节点形成一条有序链表(B树没有)m阶B+树非根节点的元素数量 x,┌ m/2 ┐ ≤ x ≤ m(B树中节点元素数量,最多是m-1,最少是┌ m/2 ┐-1)硬盘的分类机械硬盘(Hard Disk Drive,HDD原创 2020-05-25 22:38:52 · 199 阅读 · 0 评论 -
19. 跳表(Skip List)
1 跳表一个有序链表搜索、添加、删除的平均时间复杂度是多少?数组查找的时间复杂度可以达到O(logn)是因为数组支持随机访问,对于有序的数组,可以通过二分查找,达到O(logn)的效率能否利用二分搜索优化有序链表,将搜索、添加、删除的平均时间复杂度降低至 O(logn)?链表没有像数组那样的高效随机访问(O(1) 时间复杂度),所以不能像有序数组那样直接进行二分搜索优化那有没有其他办法让有序链表搜索、添加、删除的平均时间复杂度降低至 O(logn)?使用跳表(SkipList)原创 2020-05-25 22:12:55 · 307 阅读 · 0 评论 -
18. 布隆过滤器(Bloom Filter)
1 布隆过滤器如果要经常判断 1 个元素是否存在,你会怎么做?很容易想到使用哈希表(HashSet、HashMap),将元素作为 key 去查找时间复杂度:O(1),但是空间利用率不高,需要占用比较多的内存资源如果需要编写一个网络爬虫去爬10亿个网站数据,为了避免爬到重复的网站,如何判断某个网站是否爬过?很显然,HashSet、HashMap 并不是非常好的选择布隆过滤器是一种时间复杂度低、占用内存较少的方案1970年由布隆提出,它是一个空间效率高的概率型数据结构,可以用来告诉你原创 2020-05-25 21:40:50 · 281 阅读 · 0 评论 -
17. 动态规划(Dynamic Programming)
1 动态规划动态规划,简称DP,是求解最优化问题的一种常用策略动态规划中的“动态”可以理解为是“会变化的状态”没有动态规划前,通常的使用套路(一步一步优化)暴力递归(自顶向下,出现了重叠子问题)记忆化搜索(自顶向下)递推(自底向上)动态规划的常规步骤定义状态(状态是原问题、子问题的解),比如定义 dp(i) 的含义设置初始状态(边界),比如设置 dp(0) 的值确定状态转移方程,比如确定 dp(i) 和 dp(i – 1) 的关系动态规划维基百科的解释将复杂的原问题拆原创 2020-05-24 13:15:04 · 143 阅读 · 0 评论 -
16. 贪心(Greedy)+分治(Divide And Conquer)
1 贪心贪心策略,也称为贪婪策略,每一步都采取当前状态下最优的选择(局部最优解),从而希望推导出全局最优解贪心策略并不一定能得到全局最优解因为一般没有测试所有可能的解,容易过早做决定,所以没法达到最佳解贪图眼前局部的利益最大化,看不到长远未来,走一步看一步优点:简单、高效、不需要穷举所有可能,通常作为其他算法的辅助算法来使用缺点:鼠目寸光,不从整体上考虑其他可能,每次采取局部最优解,不会再回溯,因此很少情况会得到最优解贪心的应用哈夫曼树最小生成树算法:Prim、Kruskal最原创 2020-05-21 16:33:39 · 341 阅读 · 0 评论 -
15. 回溯(Back Tracking)
1 回溯回溯可以理解为:通过选择不同的岔路口来通往目的地(找到想要的结果)每一步都选择一条路出发,能进则进,不能进则退回上一步(回溯),换一条路再试树、图的深度优先搜索(DFS)、八皇后、走迷宫都是典型的回溯应用从图中不难看出来,回溯很适合使用递归,因为4做的事和根节点7做的事完全是一模一样的2 练习 – 八皇后问题(Eight Queens)在8x8格的国际象棋上摆放八个皇后,使其不能互相攻击:任意两个皇后都不能处于同一行、同一列、同一斜线上。请问有多少种摆法。剪枝回溯原创 2020-05-21 16:08:59 · 310 阅读 · 0 评论 -
14. 递归(Recursion)
1 递归(Recursion)递归:函数(方法)直接或间接调用自身。是一种常用的编程技巧函数递归调用时,栈空间的变化public static void main(String[] args) { sum(4);}private static int sum(int n) { if (n <= 1) return n; return n + sum(n - 1);}3. 递归时,每次方法调用,都会新建一个栈帧对该方法中变量进行保存,因此随着递归的深度越深,会消耗大量的栈空原创 2020-05-20 11:11:59 · 277 阅读 · 0 评论 -
13. 图(Graph)
1原创 2020-05-16 17:54:00 · 303 阅读 · 0 评论 -
12. 并查集(Union Find)
1 并查集(Union Find)假设有n个村庄,有些村庄之间有连接的路,有些村庄之间并没有连接的路设计一个数据结构,能够快速执行2个操作将两个村庄相连查询2个村庄之间是否有连接的路并查集能够办到查询、连接的均摊时间复杂度都是 O(α(n)) ,α (n) < 5并查集非常适合解决这类“连接”相关的问题并查集也叫作不相交集合(Disjoint Set)并查集有2个核心操作查找(Find):查找元素所在的集合(根节点)(这里的集合并不是特指Set这种数据结构,是指广义的数据原创 2020-05-16 16:31:21 · 274 阅读 · 0 评论 -
11. 排序(Sorting)
1 十大排序算法1.1 排序算法的稳定性(Stability)如果相等的2个元素,在排序前后的相对位置保持不变,那么这是稳定的排序算法排序前: 5, 1, 3 ???? , 4, 7, 3 ????稳定的排序: 1, 3 ???? , 3 ???? , 4, 5, 7不稳定的排序: 1, 3 ???? , 3 ???? , 4, 5, 7对自定义对象进行排序时,稳定性会影响最终的排序效果稍有不慎,稳定的排序算法也能被写成不稳定的排序算法,比如下面的冒泡排序代码是不稳定的1.2原创 2020-05-12 21:01:27 · 565 阅读 · 0 评论 -
10. 哈夫曼树、Trie、补充
1 哈夫曼树哈夫曼编码,又称为霍夫曼编码,它是现代压缩算法的基础假设要把字符串【ABBBCCCCCCCCDDDDDDEE】转成二进制编码进行传输,可以转成ASCII编码,但是有点冗长可以先约定5个字母对应的二进制,从而使编码更短注意新的编码,谁都不是谁的前缀,否则无法将二进制码解码成原字符串对应的二进制编码:000001001001010010010010010010010010011011011011011011100100,一共20个字母,转成了60个二进制位使用哈夫曼编码,可以压缩至4原创 2020-05-11 19:43:56 · 870 阅读 · 0 评论 -
9. 二叉堆
1 堆设计一种数据结构,用来存放整数,要求提供 3 个接口添加元素获取最大值删除最大值堆中获取最大值:O(1)、删除最大值:O(logn)、添加元素:O(logn)堆的性质是一种树状的数据结构(不要跟内存模型中的“堆空间”混淆)任意节点的值总是 ≥( ≤ )子节点的值如果任意节点的值总是 ≥ 子节点的值,称为:最大堆、大根堆、大顶堆如果任意节点的值总是 ≤ 子节点的值,称为:最小堆、小根堆、小顶堆堆中的元素必须具备可比较性2 二叉堆(Binary Heap)二原创 2020-05-11 18:33:54 · 398 阅读 · 0 评论 -
8. 哈希表
1 TreeMap分析时间复杂度(平均):添加、删除、搜索:O(logn)特点:Key 必须具备可比较性产生哈希表的原因在实际应用中,很多时候的需求,Key 不需要具备可比较性TreeMap平均时间复杂度还是较高,如果使用哈希表,平均时间复杂度可以达到O(1)2 哈希表(Hash Table)哈希表也叫做散列表(hash 有“剁碎”的意思)添加、搜索、删除的流程都是类似的利用哈希函数(散列函数)生成 key 对应的 index,(O(1))根据 index 操作定位数组元素原创 2020-05-10 08:33:17 · 185 阅读 · 0 评论 -
7. 集合与映射
1 集合(Set)Setpackage com.mj.set;public interface Set<E> { int size(); boolean isEmpty(); void clear(); boolean contains(E element); void add(E element); void remove(E element); void traversal(Visitor<E> visitor); public static ab原创 2020-05-10 07:02:56 · 152 阅读 · 0 评论 -
6. 红黑树
1 B树B树是一种平衡的多路搜索树,多用于文件系统、数据库的实现1 个节点可以存储超过 2 个元素、可以拥有超过 2 个子节点拥有二叉搜索树的一些性质平衡,每个节点的所有子树高度一致比较矮m阶B树的性质(m≥2)所谓的m阶,就表示节点的度最多为m根节点中可以只有一个元素,且只有两个子树对于非根节点,有特殊的要求,比根节点的元素和子树个数都要多,至少要有ceiling(m/2)-1个元素,ceiling(m/2)个子树根据子树个数的范围,重新命名B树例如4阶B树,也可以叫做(原创 2020-05-09 08:00:20 · 168 阅读 · 0 评论 -
5. 二叉树
1 树的基本概念节点、根节点、父节点、子节点、兄弟节点空树:一棵树可以没有任何节点一棵树可以只有 1 个节点,这个节点其实就是根节点子树、左子树、右子树节点的度:子树的个数树的度:所有节点度中的最大值叶子节点:度为 0 的节点非叶子节点:度不为 0 的节点层数(level):根节点在第 1 层,根节点的子节点在第 2 层,以此类推(有些教程也从第 0 层开始计算)节点的深度(...原创 2020-05-08 14:29:44 · 309 阅读 · 0 评论 -
4. 栈与队列
1 栈:Stack栈是一种特殊的线性表,只能在一端进行操作往栈中添加元素的操作,一般叫做 push,入栈从栈中移除元素的操作,一般叫做 pop,出栈(只能移除栈顶元素,也叫做:弹出栈顶元素)后进先出的原则,Last In First Out,LIFO2 队列:Queue队列是一种特殊的线性表,只能在头尾两端进行操作队尾(rear):只能从队尾添加元素,一般叫做 enQueue,...原创 2020-05-07 20:54:35 · 132 阅读 · 0 评论 -
3. 链表
1 链表(Linked List)动态数组有个明显的缺点,可能会造成内存空间的大量浪费链表能够做到想使用多少内存就申请多少内存链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的2 链表的设计成员变量设计LinkedList中很多功能与ArrayList完全相同,但具体实现不同,可以将功能相同、实现不同的内容,放入List接口,将功能相同、实现也相同的公共代码,放入抽象...原创 2020-05-07 07:36:21 · 173 阅读 · 0 评论 -
2. 动态数组
1 数据结构数据结构是计算机存储、组织数据的方式数据结构分类2 线性表具有 n 个相同类型元素的有限序列( n ≥ 0 )a1是首节点(首元素),an是尾节点(尾元素)a1是a2的前驱,a2是a1的后继3 数组顺序存储的线性表,所有元素的内存地址是连续的数组无法动态修改容量实际开发中,我们更希望数组的容量可以动态改变,称为动态数组4 动态数组的设计成员...原创 2020-05-07 00:05:58 · 170 阅读 · 1 评论 -
1. 复杂度
1 算法算法是用于解决特定问题的一系列的执行步骤使用不同算法,解决同一个问题,效率可能相差非常大2 评判算法好坏2.1 事后统计法比较不同算法对同一组输入的执行处理时间执行时间严重依赖硬件以及运行时各种不确定的环境因素必须编写相应的测算代码测试数据的选择比较难保证公正性例如算法1处理100快,但处理50慢,而算法2处理100慢,处理50快2.2 评估算法优劣的几个...原创 2020-05-06 22:12:48 · 211 阅读 · 0 评论