算法导论
再也不说我是谁
西南交通大学信息与通信工程博士三年级在读
展开
-
数据结构- 哈希表
最后是我们的哈希表。 这个东西我自己平时用不太多。所以我就转载一篇别人的博客,我觉得写的挺好的东西。 哈希表的核心就是在存储地址与存储内容之间建立一个映射关系,这样我们在找的时候就能够直接计算,而不用挨个挨个找,提高效率。 主要面临的困难就是会出现冲突,即不同的内容可能导致相同的地址。因此哈希表需要适当地冲突处理。数据结构 Hash表(哈希表)_积跬步 至千里-CSDN博客_哈希表最后就是这也是我们算法导论的最后一篇博客了。其实红黑树我也基本用的很少。我觉得应该有一个专门的框架可以直接实现红黑树转载 2021-09-24 16:21:53 · 65 阅读 · 0 评论 -
红黑树插入 - 其余的情况
今天我们接着讨论红黑树插入的其他情况,即父节点为红色的情况。Case 1 当前节点的父节点是红色,且当前节点的祖父节点的另一个子节点(叔叔节点)也是红色。 (01) 将“父节点”设为黑色。 (02) 将“叔叔节点”设为黑色。 (03) 将“祖父节点”设为“红色”。 (04) 将“祖父节点”设为“当前节点”(红色节点);即,之后继续对“当前节点”进行操作。 Case 2 当前节点的父节点是红色,叔叔节点是黑色,且当前节点是其父节点的右孩子原创 2021-09-24 16:16:24 · 67 阅读 · 0 评论 -
红黑树插入 - 父节点为黑色节点的四种情况
今天我们首先来说十二 情况中,四种最简单的情况- 父节点为黑色节点对应上一文中就是 46 76 88 这三个节点的四种情况。由于我们假设我们的节点默认为红色,因此,当我们插入之后,我们来看红黑树的性质:红黑树的定义有四条:每个节点颜色不是黑色,就是红色 根节点是黑色的 如果一个节点是红色,那么它的两个子节点就是黑色的(没有连续的红节点) 对于每个节点,从该节点到其后代叶节点的简单路径上,均包含相同数目的黑色节第一条满足, 第二条满足, 由于我们插入是红色节点,第四条不影响也满足。.原创 2021-09-24 15:41:13 · 501 阅读 · 0 评论 -
红黑树插入的12种基本情况
今天我们核心内容是看看,在插入操作时,红黑树有多少种情况。红黑树添加的基本情况与二叉平衡树类似,都一定是插入在叶子节点位置。因此,虚线位置为加入位置。很容易看出,一共有12种情况。这里,大家注意,这个图里面包含了红黑树所有的插入情况。这一点,大家需要记一下。后续文章中,我们会对12中情况分别进行讨论。最后,再一次提醒大家,面对一个比较难得东西,不要急,每天进步一点点,这样使你不会丧失兴趣,每一步要走稳!...原创 2021-09-15 16:35:22 · 253 阅读 · 0 评论 -
红黑树保持平衡的三种基本操作
上一篇文章我们提到了红黑树。这是一种比较复杂 数据结构。所以,咱么就只能一点一点地抽丝剥茧。遇到这种比较复杂的问题,咱们切记贪多求快,要一点一点的蚕食。当然了,我说的这个也只是针对大部分普通人。天赋异禀的小天才们不要对号入座哈。接着上一篇文章,我们今天来说一说红黑树保持平衡的基本三种操作。 1 变色: 红变黑 黑变红 2 左旋 3 右旋。 其中变色太简单,咱们就不说了。咱们说说左旋和右旋。旋转示意图如下:我们首先看右旋:原根节点的左孩子成为新的根节点, 原根节点变为新根节点的右孩子,注意..原创 2021-09-11 16:57:58 · 2464 阅读 · 0 评论 -
红黑树-面对大部头咱们使出堵门绝招~庖丁解牛
首先咱们要说一个事情是 红黑树其实就是一种特殊的二叉平衡树。 那咱们奇怪了,二叉平衡树哪里不好呢? 需要引入这么个改进版。 一般改进的东西肯定比不改进的东西牛,那么牛在哪里呢?回忆一下二叉平衡树的特点是 左节点的值小于 根节点 小于 右节点。那么,如果我们有 1 2 3 4 四个元素,插入二叉平衡树,可能出现下面的情况吗?这两种情况都可能出现吧。什么?还有左边这种情况?直觉上就觉得不太对吧。是的,少年,你的直觉是对的。左边这种情况效率就比较低。想想,如果我们要找 1. 左边这种情况找..原创 2021-09-05 14:47:49 · 87 阅读 · 0 评论 -
二分查找树(binary search tree)
今天开始我们就会进入一些数据结构的部分了。今天第一个要讲的是一类特殊的数据结构,二分查找树。二分查找树的特点如下:即根节点的数值一定小于左右子节点,其优势在于插入与查找时间较低为同样,我们比较关心二分查找树的创建 插入 删除首先说一下,我们在创建二分查找树的时候,也可以根据根节点数值小于子节点的规则一个一个的插入。所以创建与插入可以看成一起的。插入的时候也很简单,就是根据上述的特点,去找到一个比需要插入的值更小的根节点,然后看看插入到左节点还是右节点合适(还要考虑到后面的节点),直接插入即可。原创 2021-08-25 10:54:55 · 3584 阅读 · 0 评论 -
关于迪杰特斯拉算法基于最小堆的改进
迪杰特斯拉算法每一步需要选取离X最近的边添加入X集合中。而求解这个最小值如果能够很高效,那么可以进一步提高算法的效率。由于我们每一步选取最小的,因此我们可以计算出剩余节点离X中点的距离,然后用最小堆的数据结构来直接弹出最小值。最小堆求解最小值的算法复杂度为最小堆就是一种完全二叉树,但是要保证根节点小于左右节点。最大堆则反之。这里我们介绍最小堆的创建,插入与删除过程。创建- 先将所有元素按照二叉树结构随意插入。然后进行“自底向上调整”。假设元素为[9 3 7 6 5 1 10 2]..原创 2021-08-21 14:54:47 · 196 阅读 · 0 评论 -
继续讨论迪杰特斯拉算法正确性
上一文中我们谈到了单源路径算法 迪杰特斯拉算法。今天我们就来继续讲一下这个算法的正确性。如果有点忘记的同学们可以先点回去复习一下,尤其是注意一下迪杰特斯拉算法的贪婪规则。我们怎么证明该算法的正确性呢?老规矩,我们使用数学归纳法(一般想不到什么好办法,就用这个办法吧)。当X为空时,我们会选择与起点s点最近的点加入X,显然s到该点的最近路径选择是正确的。我们假设已经有一个X了,且所有X中节点对应的最短路径以及长度均正确存储在A[v], B[v]中。现在我们假设新加入一个点w时, 存在一条额外原创 2021-08-13 15:31:09 · 253 阅读 · 0 评论 -
最短路径算法-迪杰特斯拉算法(Dijkstra)
老规矩,我们首先给出该算法的具体流程:- X={s} %%记录有没有被探索过- A[s]=0 %% 该节点的最短路径-B[s]=[s]%% 保存该节点的最短路径- while x != v - among all edges (v,w)E, %% 边的集合 - pick one that minimize A[v] + 假设是 - add to X - set A[] = - set...原创 2021-08-11 16:07:31 · 841 阅读 · 0 评论 -
继续强联通分量-Tarjan算法
实际上Kosaraju算法在实际应用中存在一些不足。优点在于好理解。实际使用中Tarjan算法用的更多,执行效率更高。而Tarjan算法在理解了Kosaraju算法之后也是十分好理解的。关于Tarjan算法,我发现了一篇讲的特别好的博客。所以,这个算法我就直接转载了这位老兄的博客。https://blog.csdn.net/weixin_43843835/article/details/88381828有兴趣的话可以看看。讲的比较细致。...转载 2021-08-10 12:53:43 · 89 阅读 · 0 评论 -
DFS与强联通分量(strong connected component-Sccs)
今天我们来聊一下DFS计算有向图的强联通分量Sccs。老规矩,首先给出Sccs的定义。Sccs是一些节点的集合,该集合中任意两个节点u,v,存在路径u到v,同时也存在路径v到u。我们来看一个示意图我们看,a点存在一个到b的路径,b可以通过e点到达a。因此a b e构成了一个Sccs。那么我们如何求解一个图中的Sccs呢?首先,我们将上图中的Sccs缩成一个点,来看看。我们可以看到,将Sccs缩成一个点之后,示意图变简单了不少。如果我们对简化过后的示意图来进行搜索的话,我们..原创 2021-08-09 13:36:49 · 746 阅读 · 0 评论 -
DFS之拓扑排序应用
上一篇文章我们说了拓扑排序的基本思路。看起来是不是挺简单的。但是问题的关键在于,我们每一次要选择出度或者入度为0的点,如何高效选取呢?这里我们为了与DFS方便联系,我们目标就是找出度为0的点即sink node我们回忆一下,拓扑排序的基本思路,找sink node,然后将该点相关的边都删除。DFS算法什么时候停止?是不是找到sink node点的时候就不再继续向下探索了呢?将该点标记为explored之后,是不是就返回该节点的前向节点了呀。DFS将一个node标记为explored之后,是不原创 2021-08-04 08:33:06 · 488 阅读 · 0 评论 -
拓扑排序- 基本思路
所谓的拓扑排序的核心就是在一个有向图中,如果存在边u 到v, 则排序后u一定要在v的前面。其基本的排序思路如下所示:示意图如上所示。我们对这个图进行拓扑排序。我们的基本思路为:TopSort(G)- 找到一个入度为0 的点(没有前节点),输出- 删除与该点所有相连的边-重复上述步骤知道所有点被explored其执行步骤为实际上我们也可以在拓扑排序中每一步找出度为0的点,即没有后继节点输出。不过最后要将得到的序列反序。出度为0的节点一般叫做沉没节点(sin...原创 2021-08-03 11:23:20 · 1357 阅读 · 0 评论 -
图搜索算法之-深度优先 DFS
前面我们讲了BFS,本文我们讲一讲DFS。老规矩先给出DFS的伪代码DFS(graph G, start vertex s)- mark s as explored-for each edge (s,v) -if v unexplored -DFS(G,v)这里我们可以分析一下,BFS,在某个节点s,会将与s相连的所有节点v找出来,而这里我们看,只要有一个节点v与s相连,DFS就会以v作为新的起点开始往下找。所以看起来有一种打破砂锅问到...原创 2021-08-02 15:42:17 · 139 阅读 · 0 评论 -
BFS与connected components
上文中我们讲到了BFS与最短路径的关系。本文,我们聊一聊图的connected components。中文翻译好像是 等价类。等价类的意思是只要节点之间存在连通的边,则这些节点都被分在同一个类中。简单点说即图可以被分为多少块 pieces。如上图所示,这个图有三块。其实算法很简单。如下所示:- for i=1:N -if node i is not explored -BFS(G,i)我们说BFS(G,i)肯定能找到以i为...原创 2021-08-01 21:07:19 · 203 阅读 · 0 评论 -
BFS与最短路径计算
上一篇文章我们讲了广度优先搜索算法。我们提到了BFS算法有一种类似于 Layer-by-Layer 的节点搜索特点。本文中,我们继续聊一聊BFS计算最短路径的关系。BFS的流程在上一篇博客中讲了,所以我们就不多赘述了。今天我们就说一下如何在BFS的基础上实现最短路径的计算。还是沿用上一文中的示意图。这里我们假设每条边的长度都是1,当然如果每条边长度不一样,情况也是差不多的,只不过处理的时候稍微变换一点点,即只更新最短路径即可。初始的时候,我们假设s点的路径长度为P=0从s点开始BF.原创 2021-07-30 14:26:01 · 1550 阅读 · 0 评论 -
广度优先搜索算法BFS
本文我们主要讲BFS算法。BFS算法搜索的时候呈现出一种 按 层 搜索的特点,即节点看起来好像被分为不同的 layer了。具体我们还是举个例子来说明。老规矩我们先给出BFS算法的计算流程BFS(graph G, start vertex s)[all nodes are initited as unexplored]- mark s as explored- initiate Q as a empty FIFO queue, then add s into Q-whil...原创 2021-07-29 17:09:52 · 569 阅读 · 0 评论 -
一般性图搜索算法
图搜索算法是一类重要的基于图的算法。本文 给出一般化的图搜索算法的框架。图搜索算法的核心任务是从一个初始节点s,尽可能多的找到其他的点v。注意通常对于一个n个点,m条边的图,我们希望搜索算法的复杂度为,换言之,我们希望每一个点与边都不重复搜索两次。老规矩,图搜索算法的一般步骤如下:1. 初始化开始点s为explored,其他点为unexplored2. 循环直到找不到未被搜索的点3. 选择边(u,v),其中u explored,v unexplored4. ...原创 2021-07-27 17:25:09 · 1238 阅读 · 0 评论 -
最小割问题-Karger‘s algorithm
上一篇文章我们提到了最小割问题,最小割问题在研究网络最薄弱环节相关问题上具备广泛应用。而这个问题如今也依旧是一个open problem。而今天我们就介绍一种求解最小割问题的概率型算法-Karger's algorithm。 该算法是karger读博期间发现的一种非常简单的算法。其核心步骤就是我们随机在图上找两个点进行 constraction 合并操作。如下图所示:注意2,3由于合并为了一个点,所以2 3两点之间的边我们就当做没有了,同时要消除由于合并形成的自环。重复上述步骤到图只剩下两.原创 2021-07-21 10:41:10 · 3820 阅读 · 1 评论 -
基于图的第一个算法-最小割问题
上一篇博客我们提到了图与图的基本表示方法。今天我们开始接触第一个图的算法最小割问题。我们知道图就是由一些顶点和顶点之间的边所构成的。什么是割呢?其实所谓的割就是将图中的顶点二分的某一种具体的方法。即将图中顶点任意分成两部分都称为该图的一个割,注两个集合均不能为空。lemma 1: 某个图有n个顶点,则总共有个割。Proof: 每个顶点都有两个选择,但是注意两个集合都不能为空,因此共计种分法。最小割问题则是我们将图中顶点分成A B两个集合后,这样的边(头在A中,尾在B中,或者相反也行,无向图则原创 2021-07-17 17:46:16 · 815 阅读 · 0 评论 -
算法导论part-II 图的相关算法
从这一篇博客开始,我们逐渐会开始学习一些图的相关的算法了。首先我们明白一下什么时图。我们通常提到的图都是有两个组成部分:顶点,边。顶点是图的基本元素,而边则是代表顶点之间有没有连接关系。根据边的方向性,图又分为有向图和无向图两种。举个简单的例子,成都和北京,两个城市就可以看作是两个顶点。彼此间有飞机可以来往,既可以从成都到北京,又可以从北京到成都,因此这个关系可以表示为无向图。但是如果假设某一天打仗了。因为敌人的干扰,我们只能从成都到北京,而北京的飞机出不来。那么此时,就是一个有向图了。原创 2021-07-13 14:26:44 · 102 阅读 · 0 评论 -
确定性RS算法-D-RS算法
上篇博客我们分析了RS算法的复杂度。我们发现只要我们选择的pivot足够好,该算法的平均复杂度是线性的。那么我们就会考虑,我们有没有办法改进一下RS呢,让我们的算法的复杂度就是。于是就有了今天要讨论的这个算法D-RS。其实D-RS算法核心就是改进了RS算法的pivot的选择方式,保证了我们每一次都能选择到足够好的一个pivot。老规矩,我们先给出D-RS算法的流程:1. 先将数组分成5个元素一组,共计n/5个小组。2. 对这n/5个小组进行排序,并求出其对应的中位数,, k代表第k个小组原创 2021-07-12 16:10:41 · 1385 阅读 · 0 评论 -
RS算法复杂度分析
这篇博客我们接着上一篇博客的内容,我们来分析一下RS算法的复杂度。从上篇博客的lemma 1我们看到如果每一次都选择当前集合的中位数作为pivot,则RS算法复杂度为。但是实际上我们随机选择的话并不能保证总是能选到中位数。通常意义上,这样一个pivot被认为足够好,即该pivot落在当前集合的25%-75%之间。不难发现,如果我们选择了一个足够好的pivot,那么当前的集合在下一次迭代过程中任务规模至少下降25%。所以为了方便起见,我们设为一个代表第j次选到足够好的pivot所需要的随机挑选的次数的随机原创 2021-07-12 15:24:50 · 777 阅读 · 0 评论 -
解决pivot选择问题-随机选择算法(random select algorithm)
前面在讨论快速排序算法的时候,我们提到了一个事情,我们说可以在线性时间复杂度内完成对数组中位数的查找,即。今天我们就来讨论一下这个问题。我们讨论一个更加一般化的问题,即查找数组中第i大的数。老规矩,我们依然先给出算法流程,我们假设我们的函数为RS(array A, length A, order statistics i)。算法的伪代码如下:1. if n=1, return A2. 在A中随机选择一个数作为pivot p3. 将A根据p分为两个部分,一个部分全部比p小,另一部分全部原创 2021-07-11 14:27:12 · 661 阅读 · 0 评论 -
继续快速排序复杂度分析
上一篇博客我们给出了快速排序的两个结论。我们说如果随机选取pivot,则快速排序的平均复杂度为,今天主要证明上一篇博客中的lemma 2。至于一个数组的中位数能够在线性事件复杂度内查找完成,我们留在之后来进一步讲解。首先我们回忆一下快速排序的主要步骤:1. 随机选择一个元素作为pivot;2. 将原数组分为两部分,一部分都比pivot小, 另一部分都比pivot大;3. 对两部分递归步骤1和步骤2;从上面我们可以发现,快速排序的主要计算复杂度就是步骤2中,数与数的比较,其他的没有做什么其原创 2021-07-10 17:56:54 · 142 阅读 · 0 评论 -
算法入门-快速排序的初印象(quick-sort)
前面我们已经给出过一种计算复杂度为的排序算法-归并排序。这里,我们在提一种新的排序方法,快速排序。这种排序方法的平均复杂度为。为什么是平均复杂度呢?且听我慢慢道来。老规矩,先给出快速排序的基本流程:1. 随机从给定数组中选择一个数,作为pivot,标杆。2. 将数组分为两个集合,一个集合的所有数都比该pivot小,另一个集合都比该pivot大。3. 对两个集合递归重复上述操作。其基本的示意图如下所示:看到这里,大家肯定有所疑惑,就这样?能排好序吗?没关系,我们来试着证明一下。原创 2021-07-09 12:40:35 · 93 阅读 · 0 评论 -
递归算法复杂度衡量-master method
前面我们提到了两种典型的分治算法-归并排序,最近点对算法。分析复杂度的时候,咱们都是采用类似于树形结构的方式,先表达出子任务的个数,以及每个子任务的复杂度,然后将所有的复杂度进行加总。今天呢,咱们进一步给出这类递归算法复杂度衡量的重要推论-master method。以后,只要咱们给出了递归算法的递归式,就可以很方便的进行求解了。为了方便起见,咱们还是用T(n)代表某算法复杂度,输入规模为n。设复杂度的递归式为。上述递归式的含义可以解释为,每一个规模为n的大任务都会被分为a个规模为n/b的小任务,且每一原创 2021-07-08 10:25:46 · 1028 阅读 · 0 评论 -
继续分治- n点之间的最小距离
上一篇文章中,我们分析了第一种分治算法-归并排序,这个算法具备的运算复杂度。这篇文章中,我们还需要使用到这个结论,我们暂且记下。本文中,我们提出一个新的问题,二维平面上的n个点,我们要找出任意两个点间的最短距离。首先,我们考虑一下暴力求解,每两个点之间的距离我们都计算一下。那么我们总共需要计算的次数为。可以看到,暴力求解的方法的计算复杂度为n的平方。那么有没有什么办法可以让我们计算得更加快一点呢?我们可以初步考虑一个简单的例子,即首先我们假设这n个点都在一条直线上,即纵坐标都相等。且这n个点已经按照原创 2021-07-04 15:05:00 · 2023 阅读 · 0 评论 -
算法入门-从分治法开始讲起
在清楚了算法复杂度的概念之后,我们要开始慢慢接触算法设计了。我们比较算法的好坏通常就是以算法复杂度为核心指标。我们可以看到不同的算法思路,就会有不同的复杂度。分治法,说白了核心就是把一个大的问题分解为小的问题,然后当小的问题求解完成以后,按照一定的方法将小的问题的答案汇总为大问题的答案。所以,通常而言,我们也要先看看目标问题能不能用分治法来求解。今天我们就简单讨论下分治法的一个常用例子-Merge_sort(归并排序)。归并排序的核心步骤如下:1. 将需要排序的元素等分为两部分2. 将两原创 2021-06-25 21:26:05 · 118 阅读 · 0 评论 -
算法复杂度的些许补充
上面一篇文章我们给出了算法复杂度的定义以及大致的分析原则,这次,我们要对算法复杂度进行一些必要的细化与补充。让大家能够看明白为什么要遵循那四条原则,或者是一些有用的推论,能够帮助我们提高效率。...原创 2021-06-24 09:43:30 · 128 阅读 · 0 评论 -
算法导论-从算法复杂度开始说起
在各种论文中我们经常会看到算法复杂度分析。这是一个高频出现的内容。大部分的同学第一反应肯定是 什么是复杂度?算法复杂度是不是算法具体执行了多少次?其实算法复杂度是指算法的时间复杂度,其单位并不是一次具体的运算(如 加法 乘法 或者寄存器操作等),相反,凡是能够在有限时间内完成的,统称为常数时间操作,是算法复杂度的基本单位。算法的时间复杂度也不是指具体的算法执行次数,而是指随着算法输入规模增加,算法的复杂度增长的规律。因此,算法复杂度是一个极限的概念,也称为渐进复杂度。既然是极限相关的分析,所以我们先给出原创 2021-06-22 09:44:24 · 508 阅读 · 0 评论