408数据结构
408数据结构之旅
Viatorz
no pain,no gain
展开
-
408数据结构(王道版+邓俊辉版)
第一章 绪论上第一章 绪论 下第二章 向量 上第二章 向量 下第三章 列表第四章 栈与队列第五章 二叉树第六章 图第七章 搜索树第八章 高级搜索树(上)第八章 高级搜索树(下)第九章 词典第十章 优先级队列第十一章 串(上)408数据结构第二轮反思说明:按408数据结构考纲为框架,以邓俊辉版内容和王道内容结合oj进行学习2020版...原创 2019-03-01 13:28:02 · 3261 阅读 · 0 评论 -
408数据结构第二轮反思
第二轮我是用的王道教材,第一轮是用的清华大学邓俊辉的教材。在第二遍里我把王道选择题和408的数据结构大题刷了一次,总体来说在图和树那里,出算法的大题概率不高,都是讲述原理的大题,而在排序,线性表那里可能出算法大题,但也不是很难。第二遍里面,因为第一遍的积累,并没有出现理解不了的地方,但在AVL树,图的最小生成树,最短路径,拓扑排序,关键路径和kmp中很多细枝末节是我在第二轮中花费较多的地方。在复习...原创 2019-11-06 11:41:26 · 1174 阅读 · 0 评论 -
KMP算法
KMP算法是解决高效解决子串匹配查找问题的方法。一般我们使用暴力的算法可以解决子串的匹配查找问题如下图的两种方法上述两种方法虽然可以达到目的,但是效率不高,这是什么原因呢?在每次依次匹配查找的时候,很多前缀重复,根本不需要重头开始,那么有什么方法可以解决呢?这时候就引入了KMP算法去解决这个问题模式串:abcab文本串:abcacababcab首先,前四位按...原创 2019-07-28 19:06:06 · 174 阅读 · 0 评论 -
串的ADT
串是指字母按一定的顺序排列串的一些术语串的一些接口,最主要的是indexOF是判断是否有子串与P完全相同原创 2019-07-28 10:28:25 · 316 阅读 · 0 评论 -
第十一章 串(上)
串的ADTKMP算法原创 2019-07-28 10:09:01 · 171 阅读 · 0 评论 -
散列:排解冲突(2)
按上节线性试探,会导致数据的聚集,该如何解决呢?这里引入了平方试探,以平方数为距离,确定下一试探桶单元如上图所示,平方试探虽然可以解决数据聚集的问题,但留下来大量空桶,装填因子过低。所以这里引入了双向平方试探来解决如上图所示双向试探,但双向试探会出现左右两端数据冲突的现象,该如何避免?这里取表长做素数 M=4*k+3,必然可以保证查找链的前M项均互异...原创 2019-07-28 09:29:05 · 457 阅读 · 0 评论 -
散列:排解冲突(1)
可以是用多槽位法,在冲突的位置开辟空间,进行存储,类似与用向量的方法其缺点是,预留过多,空间会浪费,而且无论预留多少,在极端的情况下仍有可能不够所以我们想到了列表,使用独立链来存储冲突数据其优缺点如上图所示,更重要的是其分配的空间未必连续分布,系统缓存几乎失效所以我们这里使用开放定址,为每个桶都设置事先约定若干备用桶,它们构成一个查找链优缺点如上图所示如...原创 2019-07-27 22:42:45 · 157 阅读 · 0 评论 -
散列:散列函数
如何完成令人满意的散列呢?需要完成两个基本的任务 1 设计散列函数 2 制定预案,发生冲突后可以排解什么样的散列函数更好呢?1 确定,同一关键码总是被映射到同一地址2 快速 expected---3 满射 尽可能充分地覆盖整个散列空间4 均匀 关键码映射到散列表各位置的概率尽量接近,可有效避免聚集现象确定散列函数的一些方法1 除余法 hash(key)=key%M,...原创 2019-07-27 22:07:32 · 395 阅读 · 0 评论 -
第十章 优先级队列
完全二叉堆:结构完全二叉堆:插入与上滤完全二叉堆:删除与下滤完全二叉堆:批量建堆堆排序左式堆:结构左式堆:合并左式堆:插入与删除原创 2019-07-27 21:31:41 · 149 阅读 · 0 评论 -
第九章 词典
散列:原理散列:散列函数散列:排解冲突(1)散列:排解冲突(2)原创 2019-07-27 11:36:53 · 167 阅读 · 0 评论 -
散列:原理
如果我们用向量存储一组数据,虽然它的查询效率为是令人满意的,但是其会占用大量的存储空间,其空间效率就不令人满意了。所以我们引入了散列。首先定义桶(bucket):直接存放或间接指向一个词条,称其为桶数组/散列表 容量为M。其容量要压缩将其控制在N<M<<R,N为待存放的元素,R为实际的元素容量其通过散列函数:hash():key----->&e...原创 2019-07-27 11:36:15 · 316 阅读 · 0 评论 -
第八章 高级搜索树(下)
B-树:插入B-树:删除红黑树:动机红黑树:结构红黑树:插入红黑树:删除原创 2019-07-27 10:33:24 · 176 阅读 · 0 评论 -
B-树:结构
上图就是一个B树,其每个节点未必有两个分叉,B树会显得更宽更矮B树就是经过适当的合并,得到超级节点,如上图所示,其每d代合并:m=2^d路,m-1个关键码,上图为4路,3个关键码其优点在于多级存储系统中使用B树,可针对外部查找,大大减少I/O次数B树的定义,所谓m阶B树,即m路平衡搜素树(m>=2)外部节点的深度统一相等,所有叶节点的深度统一相等,其分支限定在([m...原创 2019-07-27 10:30:41 · 333 阅读 · 0 评论 -
B-树:动机
B树(B-)最主要的功能在于弥合不同存储级别在访问速度上的差异,实现高效的I/O。越来越小的内存要尽量的使用内存,避免去使用外存,因为内存和外存访问速度差异悬殊因为磁盘的读写每次无论多大的数据,它的操作几乎是一样快的,所以每次尽可能多的去读写数据(也就是以页或块的单位去使用缓冲区)...原创 2019-07-26 22:36:11 · 98 阅读 · 0 评论 -
伸展树(splay):双层旋转
如果使用逐层选择,会导致在最坏的情况下的分摊复杂度为,所以这里引入了新的操作,双层旋转所以可能树的情况有4种。双层旋转就是向上追溯两层,而非一层。先对其祖父旋转,之后对其父亲旋转,这就是双旋操作。由上图可以看出如果树呈现的是zig-zag或者是zag-zig,逐层操作和双层操作的效果是一样的,它的不同体现在zig-zig或者是zag-zag上在最坏的情况下进...原创 2019-07-26 18:19:07 · 783 阅读 · 0 评论 -
第八章 高级搜索树(上)
伸展树(Splay):逐层伸展伸展树(splay):双层旋转伸展树(splay):算法实现B-树:动机B-树:结构B-树:查找原创 2019-07-26 17:17:44 · 179 阅读 · 0 评论 -
伸展树(Splay):逐层伸展
首先先要了解局部性,局部性是指刚被访问过的数据,极有可能很快被再次访问。所以Splay就利用了这个性质,当某个节点v一旦被访问过,将其转移到树根,通过zig-zag操作通过zig-zag将v节点移至树根逐层伸展,自下而上,逐层伸展直到根,但是逐层伸展在最坏的情况下时间复杂度会达到,所以需要进行改进。...原创 2019-07-26 17:16:45 · 185 阅读 · 0 评论 -
AVL树:删除
删除:单旋如果要删除T3下的节点,可以进行一次右旋操作,但要注意的是,如果T0,T1和T2下面都有节点,那么旋转操作过后,高度不变所以并不会失衡。但如果T0,T1存在,T2不存在,那么旋转之后此子树的高度会减少1,那么它的祖先就会失衡。所以g经单旋调整后复衡,子树高度未必复原;更高的祖先仍可能失衡。因有失衡传播现象,可能需要做次调整删除:多旋代码如下//AVL树...原创 2019-07-25 20:56:25 · 494 阅读 · 0 评论 -
AVL树:插入
单旋插入插入节点c,若节点c小于b,则成为b的左子节点,此时a左子树深度为2,右子树深度为0,处于不平衡状态,此时执行右旋操作。右旋就是使a、b进行右旋1/4圆,使得b节点作为父节点,a节点变为b节点的右节点,b的左子树在经过右旋操作后仍是b的左子树。如果b有右子树。那么右旋后b的右子树将成为a的左子树。左旋操作与右旋操作相同注意,g经过单旋调整后复衡,子...原创 2019-07-25 20:20:39 · 243 阅读 · 0 评论 -
AVL树:重平衡
因为BST,在最坏情况下的时间复杂度为,及时在平均情况下也会达到,这不是很理想的时间复杂度,那么如果想达到理想的时间复杂度,就要对树进行平衡操作,这里就引入了BBST来完成和解决上面的问题,AVL树就是一种BBST.AVL树的平衡标准,balFacl(v)=height(lc(v))-height(rc(v)),v表示树的节点,balFacl表示平衡因子 ...原创 2019-07-25 17:44:00 · 218 阅读 · 0 评论 -
二叉排序树(BST)删除
第一种删除情况是,要删除的左右孩子不存在的情况,那么直接用左孩子或者右孩子顶替他,之后删除他即可第二种删除情况是,要删除的左右孩子都存在,那么就要先找到他的直接后继,之后相互交换,之后用第一种方法将其删除代码如下BiTree Tree_Minmum(BiTree &root) // 查找直接后继节点{ BiTree p = root; while (p->...原创 2019-07-16 22:07:27 · 208 阅读 · 0 评论 -
二叉排序树(BST)插入
先用search找到所应该要插入的位置(假定没有重复的点)之后找到对应位置,左孩子或者右孩子为空的点将其插入,所以插入的节点必然是树的叶子在构建BST时用到了插入的操作代码如下#include<iostream>#include<cstdlib>using namespace std;#define len 15typedef struct Bi...原创 2019-07-16 21:19:10 · 1566 阅读 · 0 评论 -
第七章 搜索树
二叉排序树(BST)查找二叉排序树(BST)插入二叉排序树(BST)删除AVL树:重平衡AVL树:插入AVL树:删除原创 2019-07-16 20:49:10 · 172 阅读 · 0 评论 -
二叉排序树(BST)查找
因为此前介绍的vector和list两种数据结构并不能满足高效率的动态调整,同时也能达到高效率的查找,所以这里发明了新的数据去解决这些问题,名字叫做搜索树(BST-binary search tree)。二叉排序树的中序遍历序列,必然是单调非降的,他是二叉排序树的充要条件。二叉排序树具有顺序性:任意一节点均不小于/不大于其左/右后代BST有很多变种如AVL,Splay,RedBla...原创 2019-07-16 20:48:02 · 263 阅读 · 0 评论 -
最小支撑树(最小生成树)
如下图所示,连通图G的某一无环两通子图T若覆盖G中所有的顶点,则称作G的一棵支撑树或生成树(spanning tree)。其中顶点数为n,其边数为n-1。如果其生成树中各边权值和最小,那么称其为最小生成树(可以不唯一)。实现一 Prim算法在图中G=(V;E)中,顶点集V的任一非平凡子集U及其补集V\U都构成G的一个割(cut),记作(U:V\U)。若边uv满足u属于U且...原创 2019-05-04 20:33:23 · 14960 阅读 · 1 评论 -
双连通域分解(强连通分量)
对于无向图G。若删除顶点v后G所包含的连通图增多,则称v为切割节点(cut vertex)或关节点(articulation point)。不含任何关节点的图被称为双连通图(强连通图)。任一无向图都都可以看做是若干个极大的双连通子图组合而成,这样的子图被称为双连通域(强联通分量)(bi-connected component)。下图中c就为关节点蛮力算法先通过BFS或者DFS搜索出...原创 2019-04-29 20:44:33 · 1953 阅读 · 2 评论 -
拓扑排序
拓扑排序是指,每一个顶点都不会通过边,指向其在此序列中的前驱顶点,这样的线性序列,被称为拓扑排序(topological sorting)。只有有向无环图中会存在拓扑排序,但数量不一定唯一。拓扑排序的实现方法,找到入度为0的顶点之后从图中剔除,之后将此顶点依次排列,重复上述步骤直到排序完成。实现queue<int>q; for(int i=0;i<n;i...原创 2019-04-28 17:20:39 · 118 阅读 · 0 评论 -
深度优先搜索
深度优先搜索(Depth-First Search,DFS)选取下一顶点的策略,优先选取最后一个被访问到的顶点的邻居,也可以理解为一路走到底。实现在每一个递归实例中,先将前节点v标记为(DISCOVERED)状态,在逐一对它的邻居做处理。待所有邻居均已处理完毕,将顶点v设置为VISITED的状态,便可以回溯。若顶点u处于(UNDISCOVERED)的状态,则将边(v,u)归类为树边...原创 2019-04-19 18:40:50 · 147 阅读 · 0 评论 -
广度优先搜索
各种图搜索之间的区别,体现为边分类结果的不同,以及所得遍历树(森林)的结构差异。其决定因素在于,搜索过程中的每一步迭代,将依照何种策略来选取下一接受访问的顶点。广度优先搜索的策略是,越早访问的顶点,其邻居优先被选用。BFS,借助队列Q,来保存已被发现,但尚未访问完毕的顶点。因此,任何顶点在进入该队列的同时,都被随即标记为DISCOVERED(已被发现)的状态。BFS的每一步迭代,都...原创 2019-04-19 17:40:44 · 137 阅读 · 0 评论 -
图的表示邻接表
因为邻接矩阵对于有向图而言会产生,但在实际中我们处理的边并不会达到这么多,所以邻接矩阵之所以会产生空间效率低效的问题,就是因为有大量的边未被使用,那么有什么方式可以避免这种情况?————用列表去存储,这样的方式就被称为邻接表。定点数为n,边数为e,那么邻接表的空间复杂度为,插入的时间复杂度从领接矩阵的边为了,但是判断两个点之间是否存在联边,需要顺序的时间。...原创 2019-04-18 17:48:05 · 638 阅读 · 0 评论 -
第六章 图
图的概述图的表示领接矩阵图的表示邻接表广度优先搜索深度优先搜索拓扑排序双连通域分解最小支撑树(最小生成树)原创 2019-04-18 17:21:59 · 227 阅读 · 0 评论 -
图的表示邻接矩阵
邻接矩阵(adjacency matrix)是图的最基本的实现方式,使用方阵A[n][n]表示有n个顶点构成的图,其中每个单元,各自负责描述一对顶点之间可能存在的邻接关系。对于无权图,存在(不存在)从顶点u到v的边,当且仅当A[u][v]=1(0)。下图没无向图和有向图的邻接矩阵的实例。这一方式如果推广至带权的网络,各邻接矩阵可以从布尔型改为整型或者浮点型,记录所对应边的权重。对于不存...原创 2019-04-16 21:47:48 · 5095 阅读 · 1 评论 -
图的概述
图所谓图(graph),可定义为G=(V,E)。其中V中的元素称作顶点(vertex);集合E中的元素分别对应于V中的某一对顶点(u,v),表示它们之间存在某种关系,故称作为边(edge)。如边(u,v)所对应的顶点u,v无次序,则称作无向边(undirected edge),反之如u和v不对等,则称(u,v)为有向边(directed edge)。若为无向边,则(u,v)和(v,u)...原创 2019-04-16 21:10:49 · 272 阅读 · 0 评论 -
二叉树的实现
二叉树都可以表示成如图所示的形式,npl代表堆,color为红黑色准备。插入孩子节点template<typename T> BinNodePosi(T) BinNode<T> :: insertAsLC (T const &e){ return lchild=new BinNode(e,this) ;} // 将e作为当前节点的左孩子插入二叉树...原创 2019-03-27 00:20:47 · 550 阅读 · 0 评论 -
二叉树的应用编码树
信息被转换为二进制形式的过程称作编码(encoding);反之,经过信道抵达目标后再由二进制编码恢复原始信息的过程称作解码(decoding)。那么可以由二进制数去组成一个二进制的表去表示对应的字符比如但是这样有可能会产生歧义比如解码就会产生两种版本那么这个问题如何解决?为了消除匹配的歧义性,必须保证任何两个原始字符所对应的二进制编码串,相互都不得是前缀。...原创 2019-03-26 22:24:22 · 1745 阅读 · 0 评论 -
二叉树
为什么要先讲二叉树?因为在所有的树中,都可以由二叉树去建立。每个节点的度数均不超过2的树称作二叉树。深度为k的节点,至多有个。含n个节点,高度为h的二叉树中。每个节点的度数为偶数(0,2)的树被称作为真二叉树(proper binary tree)。当叶节点只能出现在最底部的两层,且最底层叶节点均处于次底层叶节点的左侧。则称为完全二叉树(complete bi...原创 2019-03-26 17:55:46 · 640 阅读 · 0 评论 -
第五章 二叉树
树二叉树二叉树应用编码树二叉树的实现二叉树先序遍历二叉树中序遍历二叉树后序遍历二叉树层次遍历二叉树的重构(前序/后序+中序还原二叉树)...原创 2019-03-26 17:43:02 · 997 阅读 · 0 评论 -
树
为什么要引入树的概念?因为前面所学到的向量结构和列表结构都不能同时做到在常数时间内的查找和插入,删除。所以引入树的概念去将它们的优点结合起来。环路是只V(终点)=V(起点)。节点之间均有路径,称作连通图。不含环路,称作无环图。从图论的角度看,树等价于连通无环图。因此与一般的图相同,树也由一组顶点(vertex)以及联接与其间的若干条边(edge)组成。在计算机科学中,往往...原创 2019-03-26 17:41:09 · 286 阅读 · 0 评论 -
队列接口与实现
1 定义与栈一样,队列也是存放数据对象的一种容器,其中的数据对象也按照线性的逻辑次序排列。队列结构同样支持对象的插入和删除,但两种操作的范围分别被限制于队列的两端——若约定新对象只能从某一端插入其中,则只能从另一端删除已有的元素。允许取出的元素的一端称作队头,而允许插入元素的另一端称作队尾。2 接口size() 报告队列的规模(元素总数)empty() 判断队列是否为空...原创 2019-03-20 20:19:33 · 1162 阅读 · 0 评论 -
逆波兰表达式(后缀表达式)
1 转换在有运算符和操作数组成的运算中,不使用括号,即可表示带优先级的运算关系。所以他是很有必要的对于转换成为后缀表达式。中缀表达式转后缀表达式的方法如下图。中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f + g * +。方法一转换过程需要用到栈,具体过程如下:1> 如果遇到操作数,我们就直接将...原创 2019-03-20 20:04:03 · 478 阅读 · 0 评论