![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构
文章平均质量分 88
Ho_mu_ra
这个作者很懒,什么都没留下…
展开
-
所有结点对的最短路径问题:本章对于给出信息的方式的不同 最短路径和矩阵乘法
显然,对于问题:所有结点对的最短路径问题,我们需要找到图中任何两个结点间的最短路径。同时,我们能轻易得对上一章所学的Bellman_Ford或是Dijkstra算法对每个结点都调用一次而得出结果——但显然,将会浪费很多时间。以Dijkstra算法为例,若实现它的方式为数组实现,那么Extract会搜索整个数组,消耗O(|V|)的时间——加上外层嵌套的while循环,同时处理边所用到的时间为|E|,那么算法运行的总时间为O(|V|² + |E|) = O(|V|²)。而调用 n 次,也就需要O(|V|³)原创 2020-10-14 09:04:03 · 568 阅读 · 0 评论 -
单源最短路径:最短路径性质的证明
本节就之前给出的一部分性质进行严密的证明,而非通过“显然”等模糊的语句。1、三角不等式性质引理10:设G = ( V,E)为一个带权重的有向图,其权重函数 w :E→R,其源节点为s。那么对于所有边(u, v)∈E,我们有:δ(s, v) ≤ δ(s, u) + w(u, v)证明:假定 p 是从 s 到结点 v 的一条最短路径,则 p 的权重不会比任何从s 到 v 的其他路径的权重大,不过我们在此处特指了由s到u再到v的一条路径。2、最短路径估计值的松弛效果引理11:(上界性质)设原创 2020-10-09 11:16:04 · 2209 阅读 · 1 评论 -
单源最短路径: 差分约束和最短路径
在本书的29章会介绍通用的线性规划问题,即在满足一组线性不等式的条件下优化一个线性函数。而本节中所介绍的线性规划则是一种特例,可被归类在单源最短路径问题中。并可调用Bellman_Ford算法解决该问题。在此之前,先介绍何为线性规划。线性规划:在一般的线性规划中,对于不等式Ax ≤ b,我们给定的常量有:A : 一个 m×n 的矩阵; b:一个m维向量; c:一个n为向量。其中 k 维向量即代表 k 行 1 列的矩阵,即书上的列向量。(笔者注:对于不了解矩阵的同学,我们可以当作一个...原创 2020-10-07 22:58:36 · 404 阅读 · 0 评论 -
单源最短路径: Dijkstra 算法
Dijkstra 算法解决带非负权重的有向图上单源路径最短问题,若实现方法合适,则其运行时间小于 Bellman_Ford 算法。Dijkstra 算法在运行过程中维持一组关键信息:结点集合S,从源节点 s 到该集合中每个结点的最短路径已经被找到。算法将重复从V - S 中选择最短路径估计最小的结点 u,并对它进行加入到集合、对所有从 u 出发的边进行松弛。其中,我们用最小优先队列管理结点集合 V - S。与之前相同,我们用最短路径估计来作为队列中结点比较的方式。Dijkstra(G, w,原创 2020-10-05 15:52:49 · 399 阅读 · 0 评论 -
单源最短路径 Bellman-Ford 算法 和 有向无环图中的单源最短路径问题
1、Bellman-Ford 算法它解决一般情况下的单源最短路径问题,允许边的权重为负值。同时对于给定的有向图G=(V, E)和权重函数w:E→R,它返回一个判断在路径中是否存在权重为负值的环路的布尔值。Bellman_Ford(G, w, s)Initialize_Single_Source(G, s)for i = 1 to |G.V| - 1 for each edge(u, v)∈ G.E Relax(u, v, w)for each edge(u, v)∈G原创 2020-10-05 10:31:58 · 649 阅读 · 0 评论 -
单源最短路径 中的一些概念和结论
在最短路径问题中,给定一个带权重的有向图G = (V, E),和权重函数w: E ->R,图中一条路径p = <v0, v1, ……, vk>的权重 w(p)是构成该路径的所有边的权重之和:,并定义最短路径权重:δ(u, v) = min{w(p):u到v的路径},若存在该路径,否则将置为∞。在本章将讨论单源最短路径问题:给定一个图G=(V, E),我们希望找到从给定...原创 2020-10-04 23:10:26 · 483 阅读 · 0 评论 -
原型 van Emde Boas 树
(对于一些简单的数据结构,我就不写在博客上了,然而这个van Emde Boas 树是真的有问题。。)首先,先介绍在本章中n与u的用法:n:集合中当前元素的个数;u:元素可能的取值范围;同时,该数据结构将关键字限制在 0 ~ n - 1中(与计数排序有相似性)1、基本方法 1、位向量:A[0……u - 1],其中每个位置存储的是该位置上的元素是否存在。 2、叠加的二叉树结构:其中,每个结点存储的是其儿子结点是否存在的逻辑或,即:若两个儿子都不存在,...原创 2020-09-29 16:22:11 · 392 阅读 · 0 评论 -
线性时间顺序练习题
一、排序算法的下界1、在一棵比较排序算法的决策树中,一个叶节点的最小深度是多少?解:当需要排序的队列已经是排序好了的时候,这时的决策树最小:因为每一次排序并不会导致后续的元素和前面的元素进行再一次比较。此时,若共有n个元素,则需要比较 n - 1次,从而导致决策树的深度为 n - 1.2、不使用斯特林近似公式,给出lg(n!)的渐进确界。利用A.2中的技术求累加和。解:由于则= Θ(nlgn)。3、证明:对n!种长度为n的输入中的至少一半,不存在能到达线性运行时间的比...原创 2020-09-14 14:42:26 · 837 阅读 · 0 评论 -
快速排序练习题
伪代码实现:QuickSort(A,p,r) if p < r q = Partition(A, p, r); QuickSort(A, p, q-1); QuickSort(A, q+1, r);Partition(A, p, r)x = A[r];i = p-1;for j = p to r - 1 if A[j]<=x i = i+1; exchange A[i] with A[j];exchange A[i原创 2020-09-09 20:11:13 · 3443 阅读 · 1 评论 -
堆排序 练习题
6.1 堆 1、在高度为h的堆中,元素个数最多、最少分别为?解:由堆序性质,堆是一个底层完全充满的树,因此除第h层外,每层的结点个数为2^(k-1),k为当前层数。 那么元素总个数为:N = 1 + 2 + 2^2 + 2^3 + …… + 2^(h-2) + n,其中n为第n层的元素个数,满足:1≤ n ≤ 2^(h-1),则可得: 2^(h - 1) ≤N ≤ 2^h - 1。 2、证明:含 n 个元素的堆的高度为⌊lg n⌋。...原创 2020-08-27 15:39:03 · 4477 阅读 · 0 评论 -
红黑树的删除
回忆一下红黑树中之前的内容:一、基本性质:红黑性质。 1、每个结点或是红色,或是黑色。 2、根节点是黑色的。 3、每个叶节点(NIL)为黑色。 4、若一个结点是红色的,则其两个子节点都为黑色。 5、对每个结点,从该节点到所有后代叶节点的简单路径上,均包含相同数目的黑色结点。二、之后外面学习了红黑树的旋转:用来调整指针结构。Right_Rotate(T, y) x = y.left; y.left = x.r...原创 2020-08-24 12:22:04 · 197 阅读 · 0 评论 -
红黑树
之前由于大学期末复习耽搁了,同时,对于算法导论,目前已学习到第13章,红黑树,并从这一章节开始继续学习算法导论,并且打算在学习完红黑树后对前面所有章节的习题进行总结梳理。红黑树(red-black tree)是平衡搜索树中,能够保证在最坏的情况下,基本动态集合操作的时间复杂度为O(lg n)的一种。一、性质:1、红黑树确保了么欸有一条路径比其他路径长出2倍,因而是近于平衡的。2、单个节点的属性: color、key、left、right、p。若节点没有父节点或者子节点,则属性的值为 N.原创 2020-08-11 17:08:06 · 596 阅读 · 0 评论 -
最小生成树 Kruskal 和 Prim 算法
最小生成树问题:对于一个连通无向图G=(V, E),对于每条边赋予权重 w(u, v),我们希望找到一个无环子集T⊆E,满足:将所有的节点连接起来,同时具有最小的权重,即:w(T)=∑w(u, v),其中,由于T是无环且连通所有节点,因此T被成为一棵由图G生成的树,求该生成树的问题被成为最小生成树问题。1、最小生成树的形成对于一个连通无向图G=(V, E),以及权重函数w:E->R,我们希望找出图G的一棵最小生成树,而这个过程是通过贪心算法进行实现。具体的实施如下:在每次循环前,A是.原创 2020-06-04 14:58:04 · 358 阅读 · 0 评论 -
拓扑排序 及 强连通分量
对于一个有向无环图 G = (V, E),其拓扑排序是G中所有节点的一种线性次序,满足:如果图G包含边(u, v),则节点u在拓扑排序中处于v的前面。可将图的拓扑次序看作是将图的所有节点在一条水平线上展开,图的所有有向边都从左指向右。以下是伪代码实现:TOPOLOGICAL-SORT(G){ call DFS(G) to compute finishing times v.f for each vertex v //通过DFS计算每个顶点完成的时间 as each verte原创 2020-05-25 21:17:39 · 1141 阅读 · 0 评论 -
深度优先搜索
深度优先搜索:总是对最近才发现的节点v的出发边进行探索,直到该节点的所有出发边都被发现为止。一旦某个节点v的出发边都被发现,搜索则回溯到v的前驱节点。如果还存在尚未发现的节点,则深度优先搜索将这些未被发现的节点中任选一个作为新的源节点。并重复该过程,直到所有节点都被发现。注意:可以看到,在此处的限定条件是直到所有的节点都被发现为止,这也是深度优先搜索与广度优先搜索不同的地方,由于广度优先搜索常常用来寻找从特定源节点出发的最短路径,而深度优先算法则常常作为另一个算法中的子程序。正由于深度优先搜索的原创 2020-05-20 22:00:02 · 543 阅读 · 0 评论 -
BFS 算法分析
分析: void BFS(PtrToGraph G, PtrToNode S, Queue Q){ Vertex B; PtrToNode P = (PtrToNode)malloc(sizeof(struct Node)); PtrToNode R = (PtrToNode)malloc(sizeof(struct Node)); for (int i = 0; i < MaxVertexNum; i++) { G->A[i].color...原创 2020-05-16 15:24:06 · 756 阅读 · 3 评论 -
基本的图算法
注:由于数据结构与算法分析上关于图的表述过于混乱,在此使用算法导论作为教材。由于二者关于细节处可能有所出入,因此对图进行重新学习。1、图的表示。对于图G(graph)=(V,E),有两种方法进行表示。 一、邻接矩阵。 二、邻接链表。 其中,邻接矩阵用于稠密图,即边的条数|E|接近|V|²的情形。而邻接链表通常用于稀疏图,即|E|<<|V|²的情形。在实际的应用中,对于邻接链表的运用远远大于对于邻接矩阵的运用。因此,接下来会对邻接链表进行描述和介绍...原创 2020-05-14 15:51:43 · 382 阅读 · 0 评论 -
图论算法 若干定义
一、若干定义。 图(graph)、顶点(Vertex)、边(Edge)等一些基础概念: 1、图:一个图( graph ) G = (V , E)是由顶点( vertex )和边( edge )的集合E所组成的,其中的V即顶点的集合,E即边的集合。 2、边:在图中,一条边由图中顶点集中的两个点v, w组成,这两个点被描述为点对(v, w),这个边有时候也被称作弧( arc )。 3、有序和有向: 先介绍点对(v, w)有序的概念:即(v, w...原创 2020-05-13 22:23:22 · 592 阅读 · 0 评论 -
不相交ADT 灵巧求并算法
回忆上一次文章中,Union操作并没有规定具体让哪棵树成为为另一棵树的子树。由此可以看出,该Union操作是任意的,我们如果想要对数据进行寻找等操作就会显得无迹可寻。同时,该方法的合并并没有合并到一棵树的根节点上,思考:当合并到原本的树的最深的节点时,合并后的深度无疑为大大增加,这样就会使得后续的 Find 和 Union 花费更多的时间。因此,出现了两种改进该Union的方法。其一、按大小求并(union-by-size)。顾名思义,该方法将含有节点的数目更少的树合并另一棵到根节点上。对于这种方法原创 2020-05-12 10:57:36 · 430 阅读 · 0 评论 -
不相交ADT的基本数据结构
由于该系列文章标题为数据结构,故书中的第七章排序就不再此分析了。直接跳到第八章的不相交ADT:这种数据结构实现例程仅需要几行代码。1、等价关系。在集合S上定义运算R(relation),对于a, b∈S,运算aRb返回类型为布尔型变量,即仅有 true 和 false 。当aRb = true 时,则称a、b有关系。 对于定义的该运算,有三条性质:(其中 aRb 则直接代表 aRb = true) 1、自反性:对所有的a∈S,均有aRa; 2、对称性:aRb...原创 2020-05-11 10:11:39 · 225 阅读 · 0 评论 -
二项队列
回忆一下左叉堆和斜堆。二者进行插入,删除的平均时间为O(log N)。虽然说已经够为快速,但前人还发明了另外一种不仅能将最坏的操作时间减少至O(logN),同时插入操作的时间为Θ(N)的数据结构:二项队列(binomial queue)。1、二项队列结构二项队列不同于之前的优先队列之处在于:二项队列是一棵堆序的树的集合,因此称之为森林(forest)。其中的每一棵树为二项树(binomial tree)。二项树的表示有两种方式。第一种:(图片来源见水印)可以看到,假设B0..原创 2020-05-09 15:53:13 · 297 阅读 · 0 评论 -
左式堆的操作 及 斜堆
在介绍左式堆的操作之1前,我们先回忆下左式堆的性质:对于堆中的每一个节点X,左儿子的零路径长至少与右儿子的零路长相同。并由此产生了以下结论:1、左式堆是不平衡的,其偏重于向左增加深度。2、对于任意一个节点X,从该节点出发持续向右,则会得到最短的零路径长。3、在右路径上有 r 个节点的左式堆必然至少有2^r - 1个节点。由于左式堆的实现是为了满足普通的二叉堆不能实现的 Mer...原创 2020-05-08 10:06:22 · 351 阅读 · 0 评论 -
其他堆的操作
由于对于最小堆来说(即上文介绍的堆),其堆序性质是要求父节点必须小于子节点。则在最小堆寻找最大的元素必然会遍历整个堆。同时,如果想要找到特定的某个元素,必须对整个堆进行搜索。同时,要知道元素在所有数据中所处的位置,就需要通过其他的数据结构来进行实现。因为堆所具有的两个性质:结构性(完全二叉树)和堆序性并不能保证能确定元素的位置。线性搜索整个数组,则需要的时间为O(n), 在元素过多的时候会浪费...原创 2020-05-07 19:54:20 · 218 阅读 · 0 评论 -
优先队列 堆
1、模型。优先队列和(队列与二叉树)有着相似的模型。通过对比二者可以更好的了解优先队列的模型。优先队列 队列 二叉树 Insert Enqueue Insert DeleteMin Dequeue Delete static int Succ(int Value, Queue Q){ if (++Val...原创 2020-04-30 09:52:03 · 148 阅读 · 0 评论 -
再散列 与 可扩散列
再散列 主要解决对于使用平方探测的开放定址法,表的元素填的太满从而导致操作的运行时间过长 的问题。主要思路就是建立一个两倍大的表,并将元素新散列到第二个表中。在事前可能会好奇:为什么不直接根据对于数据的估计创建一个相对大的散列表,而要用到再散列的方法。我的想法是:1、使用散列表时,数据往往十分多,此时创建一个大的散列表不但不会显著提高运行时间,同时还会浪费大量的空间,这是没有意义的。...原创 2020-04-29 09:12:30 · 290 阅读 · 0 评论 -
开放定址法
首先,先介绍一个新的参数 :装填因子(load factor)λ=散列表中元素的个数/散列表的大小。表的平均长度为λ,则不成功的查找需要的时间为λ,而成功的查找需要1+λ/2。之后再对分离链接法的缺点进行梳理总结。一、该方法需要语言支持指针。二、由于指针的存在,对指针所指向的空间的分配地址需要时间。因此,出现了一种仅由数组实现的方法:开放地址法。此方法即在冲突发生时,通过...原创 2020-04-28 21:07:31 · 2876 阅读 · 0 评论 -
复习 散列(数据结构 c语言版)
散列表(HashTable): 以平均时间O(n)执行 插入、删除、查找 等操作,含有关键字(即数组中存储的元素,可以是字符串、整数等)、具有固定大小(TableSize)的数组。散列函数(Hash function):每个关键字通过该函数可映射到范围0~TableSize-1内(必然会使用求余运算)。如何映射?Index Hash(const char *Key, int Tab...原创 2020-04-21 22:06:24 · 337 阅读 · 0 评论