![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
siwluxuefeng
后知后觉
展开
-
重温算法Day25:哈希算法的应用
哈希算法:将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制值串就是哈希值。hash算法应用安全加密、MD5(MD5 Message-Digest Algorithm,MD5 消息摘要算法)SHA(Secure Hash Algorithm,安全散列算法)DES(Data Encryption Standard,数据加密标准)AES(Advanced Encryption Standard,高级加密标准)鸽巢原理(也叫抽屉原理)。原创 2020-05-30 00:01:25 · 206 阅读 · 0 评论 -
重温算法Day24:位图与布隆过滤器
位图(BitMap)位图,就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在的。位图其实是用数组实现的,数组的每一个元素的每一个二进制位都可以表示一个数据在或者不在,0表示数据存在,1表示数据不存在。因为比特位只有两种状态,要不是0,要不就是1,所以位图其实就是一种直接定址法的哈希,只不过位图只能表示这个值在或者不在。布隆过滤器(Bloom Filter)使用 K 个哈希函数,对同一个数字进行求哈希值,那会得到 K 个不同的哈希值,我们分别记作原创 2020-05-25 23:20:39 · 188 阅读 · 0 评论 -
B树与B+树
B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。B+树中的B代表平衡(balance),而不是二叉(binary),因为B+树是从最早的平衡二叉树演化而来的。在讲B+树之前必须先了解二叉查找树、平衡二叉树(AVLTree)和平衡多路查找树(B-Tree),B+树即由这些树逐步优化而来。二叉查找树二叉树具有以下性质:左子树的键值小于根的键值,右子树的键值大于根的键值。如下图所示就是一棵二叉查找树,对该二叉树的节点进行查找发现深度为1的节点的查找次数为1,深...转载 2020-05-23 14:36:07 · 216 阅读 · 1 评论 -
重温算法Day23:B+树
树中的节点并不存储数据本身,而是只是作为索引。除此之外,我们把每个叶子节点串在一条链表上,链表中的数据是从小到大有序的。如果我们要求某个区间的数据。我们只需要拿区间的起始值,在树中进行查找,当查找到某个叶子节点之后,我们再顺着链表往后遍历,直到链表中的结点数据值大于区间的终止值为止。所有遍历到的数据,就是符合区间值的所有数据。当数据量很大的时候,如果将索引存储在内存中,尽管内存访问的速度非常快,查询的效率非常高,但是,占用的内存会非常多。如果把索引存储在硬盘中,而非内存中。但硬盘是一个非常.原创 2020-05-23 14:32:03 · 231 阅读 · 0 评论 -
重温算法Day22:拓扑排序
拓扑排序:有向无环图如果 a 先于 b 执行,也就是说 b 依赖于 a,那么就在顶点 a 和顶点 b 之间,构建一条从 a 指向 b 的边。而且,还要是一个有向无环图,也就是不能存在像 a->b->c->a 这样的循环依赖关系。Kahn 算法如果 s 需要先于 t 执行,那就添加一条 s 指向 t 的边。所以,如果某个顶点入度为 0, 也就表示,没有任何顶点必须先于这个顶点执行,那么这个顶点就可以执行了。找出一个入度为 0 的顶点,将其输出到拓扑排序的结果序列中,且把这个顶点从原创 2020-05-21 00:30:04 · 124 阅读 · 0 评论 -
重温算法Day21:跳表
每两个(三个、五个)结点提取一个结点到上一级,我们把抽出来的那一级叫作索引或索引层。你可以看我画的图。图中的 down 表示 down 指针,指向下一级结点。在第一级索引的基础之上,每两个(三个、五个)结点就抽出一个结点到第二级索引。链表加多级索引的结构,就是跳表。每两个结点会抽出一个结点作为上一级索引的结点,那第一级索引的结点个数大约就是 n/2,第二级索引的结点个数大约就是 n/4,第三级索引的结点个数大约就是 n/8,依次类推,也就是说,第 k 级索引的结点个数是第 k-1 级索引的结点个数的原创 2020-05-20 23:25:39 · 124 阅读 · 0 评论 -
重温算法Day20:动态规划
背包问题对于一组不同重量、不可分割的物品,我们需要选择一些装入背包,在满足背包最大重量限制的前提下,背包中物品总重量的最大值。把整个求解过程分为 n 个阶段,每个阶段会决策一个物品是否放到背包中。每个物品决策(放入或者不放入背包)完之后,背包中的物品的重量会有多种情况,也就是说,会达到多种不同的状态,对应到递归树中,就是有很多不同的节点。我们把每一层重复的状态(节点)合并,只记录不同的状态,然后基于上一层的状态集合,来推导下一层的状态集合。我们可以通过合并每一层重复的状态,这样就保证每一层不同原创 2020-05-16 18:01:11 · 170 阅读 · 0 评论 -
重温算法Day19:分治思想
分治算法是一种处理问题的思想,递归是一种编程技巧。实际上,分治算法一般都比较适合用递归来实现。分治算法的递归实现中,每一层递归都会涉及这样三个操作:分解:将原问题分解成一系列子问题;解决:递归地求解各个子问题,若子问题足够小,则直接求解;合并:将子问题的结果合并成原问题。分治算法能解决的问题,一般需要满足下面这几个条件:原问题与分解成的小问题具有相同的模式;原问题分解成的子问题可以独立求解,子问题之间没有相关性,这一点是分治算法跟动态规划的明显区别,等我们讲到动态规划的时候,会详细对比这两种算法;原创 2020-05-12 13:42:13 · 151 阅读 · 0 评论 -
重温算法Day18:贪心算法
分糖果我们有 m 个糖果和 n 个孩子。我们现在要把糖果分给这些孩子吃,但是糖果少,(m<n),所以糖果只能分配给一部分孩子。每个糖果的大小不等,这 m 个糖果的大小分别是 s1,s2,s3,……,sm。除此之外,每个孩子对糖果大小的需求也是不一样的,只有糖果的大小大于等于孩子的对糖果大小的需求的时候,孩子才得到满足。假设这 n 个孩子对糖果大小的需求分别是 g1,g2,g3,……,gn。我的问题是,如何分配糖果,能尽可能满足最多数量的孩子?对于一个孩子来说,如果小的糖果可以满足,我们就没必原创 2020-05-12 13:29:26 · 283 阅读 · 0 评论 -
重温算法Day17:图及图的遍历
如何在内存中存储图这种数据结构邻接矩阵(Adjacency Matrix)邻接矩阵的底层依赖一个二维数组。对于无向图来说,如果顶点 i 与顶点 j 之间有边,我们就将 A[i][j]和 A[j][i]标记为 1;对于有向图来说,如果顶点 i 到顶点 j 之间,有一条箭头从顶点 i 指向顶点 j 的边,那我们就将 A[i][j]标记为 1。同理,如果有一条箭头从顶点 j 指向顶点 i 的边,我们就将 A[j][i]标记为 1。对于带权图,数组中就存储相应的权重。缺点:浪费空间。无向图会浪费一半,原创 2020-05-12 00:02:03 · 224 阅读 · 0 评论 -
重温算法Day14:堆
堆”(Heap)堆是一个完全二叉树;堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。堆存储:数组中下标为 i 的节点的左子节点,就是下标为 i∗2 的节点,右子节点就是下标为 i∗2+1 的节点,父节点就是下标为 2i 的节点。堆排序:大致分解成两个大的步骤,建堆和排序。建堆:方式1:从下往上堆化:在堆中插入一个元素的思路。尽管数组中包含 n 个数据,但是我们可以假设,起初堆中只包含一个数据,就是下标为 1 的数据。然后,我们调用前面讲的插入操作,将下标从 2 到 n 的数据依.原创 2020-05-08 22:47:27 · 153 阅读 · 0 评论 -
重温算法Day16:Trie树
Trie树:搜索引擎的搜索关键词提示功能一种专门处理字符串匹配的数据结构,就是利用字符串之间的公共前缀,将重复的前缀合并在一起。英语的单词的话,就是26个字母,也就是树有26个叉。两个操作:一个是将字符串集合构造成 Trie 树。一个是在 Trie 树中查询一个字符串。通过一个下标与字符一一映射的数组,来存储子节点的指针。假设我们的字符串中只有从 a 到 z 这 26 个小写字母,我们在数组中下标为 0 的位置,存储指向子节点 a 的指针,下标为 1 的位置存储指向子节点 b 的指针,以原创 2020-05-11 13:00:12 · 143 阅读 · 0 评论 -
重温算法Day15:字符串匹配
BF 算法和 RK 算法BF算法(朴素匹配算法)(暴力匹配):在主串中,检查起始位置分别是 0、1、2…n-m 且长度为 m 的 n-m+1 个子串,看有没有跟模式串匹配的。RK算法:通过哈希算法对主串中的 n-m+1 个子串分别求哈希值,然后逐个与模式串的哈希值比较大小。如果某个子串的哈希值与模式串相等,那就说明对应的子串和模式串匹配了。因为哈希值是一个数字,数字之间比较是否相等是非常快速的,所以模式串和子串比较的效率就提高了。假设要匹配的字符串的字符集中只包含 K 个字符,我们可以用一个 .原创 2020-05-10 17:18:40 · 197 阅读 · 0 评论 -
重温算法Day13:二叉树
在计算机科学中,数据的相对大小比绝对的数值重要,出于很多数据比大小的需求以及其他一些需求,就产生了一个抽象的数据结构——二叉树二叉树可以做很多事情,比如排序、快速查找到某一个数值、根据网站目录结构下载所有网页、组织里的管理结构。所有能够对应到二叉树的问题,都有一些共性,解决它们之间问题的方法是可以触类旁通的。排序二叉树可以直接完成排序,因为它有一个很好的性质,就是它左右两个分叉可以和比较...原创 2020-05-07 17:45:48 · 195 阅读 · 0 评论 -
重温算法Day12:散列表
散列表来源于数组,它借助散列函数对数组这种数据结构进行扩展,利用的是数组支持按照下标随机访问元素的特性。散列表两个核心问题是散列函数设计和散列冲突解决。散列冲突有两种常用的解决方法,开放寻址法(线性探测、二次探测、双重散列)和链表法(常用)。散列函数设计的好坏决定了散列冲突的概率,也就决定散列表的性能。链表法是一种更加常用的散列冲突解决办法每个“桶(bucket)”或者“槽(slot)”会...原创 2020-04-27 22:41:42 · 298 阅读 · 0 评论 -
重温算法Day11:二分查找
二分查找依赖的是数组,找针对的是有序数据,数据量太小或太大都不适合二分查找。没找到二分查找有什么应用场景实现int sqrt(int x)函数。计算并返回x的平方根,其中x 是非负整数。由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去func mySqrt(x int) int { left, right := 1, x for left...原创 2020-04-26 23:29:22 · 152 阅读 · 0 评论 -
重温算法Day10:线性排序-桶排序、计数排序、基数排序
桶排序(Bucket sort)将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行排序。桶内排完序之后,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了。如果要排序的数据有 n 个,我们把它们均匀地划分到 m 个桶内,每个桶里就有 k=n/m 个元素。每个桶内部使用快速排序,时间复杂度为 O(k * logk)。m 个桶排序的时间复杂度就是 O(m * k * logk)。...原创 2020-04-23 23:02:10 · 173 阅读 · 0 评论 -
重温算法Day9:归并和快排
归并排序:先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。先是自顶向下细分,再自底向上合并。复杂度相当于N乘以log(N)。参考:https://blog.csdn.net/Linzhongyilisha/article/details/100110826假设对 n 个元素进行归并排序需要的时间是 T(n),那分解成两个子数...原创 2020-04-22 23:16:37 · 141 阅读 · 0 评论 -
重温算法Day7:递归
递归是一种应用非常广泛的算法递归需要满足的三个条件1. 一个问题的解可以分解为几个子问题的解2. 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样3. 存在递归终止条件写递归代码最关键的是写出递推公式,找到终止条件示例:有 n 个台阶,每次你可以跨 1 个台阶或者 2 个台阶,请问走这 n 个台阶有多少种走法?分析:n=1时,1种;n=2时,2种;n>2...原创 2020-04-20 22:43:32 · 130 阅读 · 0 评论 -
重温算法Day6:队列
队列特点是先进先出,主要的两个操作是入队和出队入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取一个元素。阻塞队列:是一个“生产者 - 消费者模型”,比如golang语言中的chan,就是一个阻塞的queue。阻塞队列可以用于数据库连接池的设计。db连接数是有限的,当用完后,如果再来拿db连接,将被阻塞,直到有使用完的将db连接归还。并发队列:线程安全...原创 2020-04-19 23:08:17 · 143 阅读 · 0 评论 -
重温算法Day5:栈
栈是一种“操作受限”的线性表函数调用栈操作系统给每个线程分配了一块独立的内存空间,这块内存被组织成“栈”这种结构, 用来存储函数调用时的临时变量。每进入一个函数,就会将临时变量作为一个栈帧入栈,当被调用函数执行完成,返回之后,将这个函数对应的栈帧出栈int main() { int a = 1; int ret = 0; int res = 0; ret ...原创 2020-04-18 18:33:47 · 102 阅读 · 0 评论 -
重温算法Day4:链表
头结点用来记录链表的基地址。有了它,我们就可以遍历得到整条链表。尾结点指针不是指向下一个结点,而是指向一个空地址 NULL,表示这是链表上最后一个结点。链表随机访问的性能没有数组好,需要 O(n) 的时间复杂度。单纯的删除操作时间复杂度是 O(1),但遍历查找的时间是主要的耗时点,对应的时间复杂度为 O(n)注意点:留意边界条件处理:链表为空、只有一个结点或两个结点、处理头结点和尾...原创 2020-04-18 18:11:11 · 123 阅读 · 0 评论 -
重温算法Day3:数组
数组主要是对概念的理解:1.数组(Array):一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。2.线性表(Linear List):线性表上的数据最多只有前和后两个方向;非线性表:数据之间并不是简单的前后关系。3.数组支持随机访问,根据下标随机访问的时间复杂度为 O(1);插入和删除的平均时间复杂度:O(n)4.如果数组只是被当作一个存储数据的集合。在这种情况下...原创 2020-04-15 23:32:24 · 132 阅读 · 0 评论 -
重温算法Day2-复杂度分析下
复杂度分析(下)复杂度的4种case:最好、最坏、 平均、均摊。这里重点说下均摊case. // array表示一个长度为n的数组 int[] array = new int[n]; int count = 0; void insert(int val) { if (count == array.length) { int sum = 0; ...原创 2020-04-14 22:25:39 · 118 阅读 · 0 评论 -
重温算法-Day1:复杂度分析上
最近加入了个重温算法的群,60天将常用的数据结构和算法过一遍,要求每周至少打卡3次。在时间允许的情况下,每天晚上看上1到2个小时,巩固算法还是很不错的。在重温的同时,我将笔记整理到到此。打卡Day1:今天学复习了“复杂度分析上”,整理如下:数据结构和算法的目的是减少资源占用和响应时间,提高执行效率。因此,需要有统计资源占用和响应时间的考量指标。于是,空间复杂度和时间复杂度就诞生了。时间...原创 2020-04-13 23:11:26 · 146 阅读 · 1 评论 -
13-快速排序
快速排序(QuickSort)如果要排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为 pivot(分区点)遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间,如下图:以5作为分区点数组 p 到 r 之间的数据就被分成了三个部分:前面 p 到 q-1 之间都是小于 ...原创 2019-10-23 22:14:30 · 144 阅读 · 0 评论 -
8-栈
特性:操作受限的线性表,只允许在一端插入和删除数据,后进先出。数组或链表确实可以替代栈,但是,特定的数据结构是对特定场景的抽象,而且,数组或链表暴露了太多的操作接口,操作上的确灵活自由,但使用时就比较不可控,自然也就更容易出错。栈主要包括两个操作,入栈和出栈。用数组实现的栈叫顺序栈;用链表实现的栈叫链式栈;时间复杂度O(1),个别情况下O(n),如自动扩容时,进行完...原创 2019-08-14 13:01:20 · 97 阅读 · 0 评论 -
9.队列
特点:先进先出,一种操作受限的数据结构;两个基本操作:入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取一个元素。顺序队列:数组实现,队列大小受限;链式队列:链式实现,可无限排队,可能导致排队等待,响应时间长;队列需要两个指针:一个是 head 指针,指向队头;一个是 tail 指针,指向队尾。调用两次出队操...原创 2019-08-19 12:48:16 · 249 阅读 · 0 评论 -
3.时间复杂度分析
复杂度分析是整个算法的精髓。从 CPU 的角度来看,这段代码的每一行都执行着类似的操作:读数据-运算-写数据。尽管每行代码对应的 CPU 执行的个数、执行的时间都不一样,但是,我们这里只是粗略估计,所以可以假设每行代码执行的时间都一样,为 unit_time。所有代码的执行时间 T(n) 与每行代码的执行次数 n 成正比大 O 复杂度表示法粗略地估计算法的执行效率的方法;T...原创 2019-08-07 13:33:37 · 222 阅读 · 0 评论 -
4.数组
数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。线性表(Linear List):数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。如:数组,链表、队列、栈等也是线性表结构。非线性表:在非线性表中,数据之间并不是简单的前后关系。比如二叉树、堆、图等。第二个是连续的内存空间和相同类型的数据...原创 2019-08-08 09:36:56 · 87 阅读 · 0 评论 -
2.数据结构与算法的理解
数据结构是一组数据的存储结构;算法是操作数据的方法;数据结构是静态的,是组织数据的一种方式,是为算法服务的;算法要用在特定的数据结构上,如:1.二分查找与数组的随机访问;2.汽车与公路,火车与铁轨,飞机与机场轨道及空中航线10个常见的数据结构:数组,链表,栈,队列,算列表,二叉树,堆,跳表,图,Trie树10个算法:递归,排序,二分查找,搜索,...原创 2019-08-05 09:45:30 · 99 阅读 · 0 评论 -
10.递归
递归是一种应用非常广泛的算法(或者编程技巧)很多数据结构和算法的编码实现都要用到递归,比如 DFS 深度优先搜索、前中后序二叉树遍历等等递归需要满足的三个条件1. 一个问题的解可以分解为几个子问题的解2. 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样3. 存在递归终止条件分析:有 n 个台阶,每次你可以跨 1 个台阶或者 2 个台阶,请问走这 n 个台...原创 2019-08-24 16:57:44 · 179 阅读 · 0 评论 -
5.链表(上)
应用:LRU缓存淘汰算法链表也是一种线性表。链表的内存结构是不连续的内存空间,将一组不连续的内存空间串联起来,从而进行数据存储的数据结构。链表中每个内存块儿被称为节点Node, 节点除了存储数据外,还需要记录链表上指向下一个节点的地址,即后继指针next.链表特点1.插入、删除数据效率O(1)级别(只需要改指针).随机访问效率O(n)级别。(需要从链表头到链...原创 2019-08-12 22:36:27 · 131 阅读 · 0 评论 -
6.链表(中)golang链表
双链表实现单链表实现链表中环的检测两个有序的链表合并删除链表倒数第 n 个结点求链表的中间结点1.golang源码中,双链表的实现package mainimport ( "fmt")func main() { // 创建一个链表 alist := list.New() fmt.Println("Size before : ", alist...原创 2019-08-12 23:25:23 · 299 阅读 · 0 评论 -
7-链表:(下)LRU缓存
1. 原理LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,如果数据最近被访问过,那么将来被访问的几率也更高。依据此原理,可以设计微服务的二级缓存结构,用于存储经常访问的热数据,实现避免频繁访问后端数据库的相同数据逻辑。当使用该缓存当做二级缓存时,需要保证缓存中数据和后端数据的一致性。2. 实现lrucache实现是使用一...原创 2019-08-12 23:44:37 · 157 阅读 · 0 评论 -
Go-Map
map是对散列表的引用map的类型是map[k],v, k和v是键和值对应的数据类型。所有的键拥有相同的数据类型,所有的值也拥有相同的类型。键的类型k, 必须是可以通过操作符 == 比较的类型。换句话说,键类型的值必须要支持判等操作。由于函数类型、字典类型和切片类型的值并不支持判等操作,所以字典的键类型不能是这些类型。V没有限制。因为 map根据 key 来计算 va...原创 2019-08-17 13:46:30 · 114 阅读 · 0 评论 -
Go-interface
转载:https://www.cnblogs.com/zhangweizhong/p/9526331.html1. 什么是interface接口 interface 是GO语言的基础特性之一。可以理解为一种类型的规范或者约定。它跟java,C# 不太一样,不需要显示说明实现了某个接口,它没有继承或子类或“implements”关键字,只是通过约定的形式,隐式的实现interface...转载 2019-08-17 14:23:39 · 206 阅读 · 0 评论 -
11.排序-冒泡、插入、选择
插入排序和冒泡排序的时间复杂度相同,都是 O(n2),我们更倾向于使用插入排序算法。原因:xxx如何分析一个排序算法:1执行效率(1)最好情况、最坏情况、平均情况时间复杂度(2)时间复杂度的系数、常数 、低阶小规模数据,同阶比较,系数和常数也很重要(3)比较次数和交换(或移动)次数2.内存消耗原地排序,空间复杂度是o(1)。3.稳定性如果...原创 2019-08-27 19:32:29 · 140 阅读 · 0 评论 -
12.归并排序
归并排序(Merge Sort)先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了分之思想,分而治之。分治是一种解决问题的处理思想,递归是一种编程技巧递推公式:merge_sort(p…r) = merge(merge_sort(p…q), merge_sort(q+1…r))终止条件: p >= r 不用...原创 2019-08-28 00:06:49 · 216 阅读 · 0 评论 -
1.为什么学习数据结构和算法
为什么学习数据结构和算法1.直接好处:写出性能更优的代码;2.算法,是解决问题的思路和方法,可应用到生活中的其它方面。3.训练大脑的思考能力,逻辑思维训练。学习算法的有效方法1.动手写2.复杂度分析法(重点),考量效率和复杂度分析3.找重点学习,最常用的,最基础的4.清楚它的来历,自身的特点,适合解决的问题,实际应用场景;学习技巧1.边学边练,适...原创 2019-08-05 09:43:45 · 141 阅读 · 0 评论