数据结构与算法
文章平均质量分 95
PeterBishop0
一起进步!
展开
-
Tarjan算法 详解+心得
Tarjan算法是由Robert Tarjan(罗伯特·塔扬,不知有几位大神读对过这个名字) 发明的求有向图中强连通分量的算法。 预备知识:有向图,强连通。 有向图:由有向边的构成的图。需要注意的是这是Tarjan算法的前提和条件。 强连通:如果两个顶点可以相互通达,则称两个顶点 强连通(strongly connected)。如果有向图G的每两个顶点都 强连通,称G是一个强连通...转载 2019-10-22 13:50:16 · 698 阅读 · 0 评论 -
背包问题的顺序和逆序
直接参考https://blog.csdn.net/yandaoqiusheng/article/details/84929357原创 2019-10-22 13:48:44 · 1403 阅读 · 0 评论 -
凸包的直径——旋转卡壳
如果想要知道怎么求凸包的直径先去学习一下怎么求解凸包点这里去看凸包好了现在知道了凸包是什么我们很显然可以得出,品面内最远的点对一定在凸包上面(为啥自己想呀)而凸包的直径也就是凸包上最远点对的距离。继续,考虑如何求解最远点对暴力枚举?显然不一定所有点都会在凸包上,显然比O(n^2)的枚举的效率会更加优秀(但是求解凸包还有一个O(nlogn))那么,有没有什么好方法能够求解出最...转载 2019-10-22 13:45:52 · 760 阅读 · 0 评论 -
并查集
代码实现如下: const int N=100;int father[N];void Init(int n){ for(int i=1;i<=n;i++)//初始化 father[i]=i;}int Find(int x){//找祖先 if(x!=father[x]) ...原创 2018-10-03 22:50:40 · 254 阅读 · 0 评论 -
KMP详解
KMP算法应该是每一本《数据结构》书都会讲的,算是知名度最高的算法之一了之后也在很多地方也都经常看到讲解KMP算法的文章,看久了好像也知道是怎么一回事,但总感觉有些地方自己还是没有完全懂明白。这两天花了点时间总结一下,有点小体会,我希望可以通过我自己的语言来把这个算法的一些细节梳理清楚,也算是考验一下自己有真正理解这个算法。 什么是KMP算法:KMP是三位大牛:D.E.Knuth、J....原创 2018-10-01 22:29:08 · 2725 阅读 · 2 评论 -
二分图算法
二分图基础知识首先什么是二分图顾名思义就是能分成两个部分的图要注意的是,‘分’的是点并且这两个集合(这里我们称作X集合和Y集合)内部所有的点之间没有边相连,也就是说X集合中任何两点之间都不会有边相连, Y亦然 定理1:无向图G为二分图的一个充要条件是 1、G中至少包含两个顶点 2、G中所有的回路长度都必须是偶数 接下来是一些概念:匹配:设G=<V, E>...原创 2018-09-19 10:10:50 · 17138 阅读 · 0 评论 -
快速幂和矩阵快速幂(取模)算法
对于普通类型的求a^n,我们的求法是不是a*a*a*a....,这样乘以n次,时间复杂度为O(n),对于普通n比较小的我们可以接受,然而当n比较大的时候,计算就慢了,所以我们就去寻找更快捷的计算方法!例如:我们要求2^8,我们通过当为偶数的时候,a^n=(a*a)^(n/2),当n为奇数时,a^n=a*(a*a)^(n/2)的形式,是不是可以转化为4^4->8^2->64^1,就可...原创 2018-09-11 14:36:23 · 18279 阅读 · 7 评论 -
Floyd-傻子也能看懂的弗洛伊德算法(转)
暑假,小哼准备去一些城市旅游。有些城市之间有公路,有些城市之间则没有,如下图。为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程。 上图中有4个城市8条公路,公路上的数字表示这条公路的长短。请注意这些公路是单向的。我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径。这个问题...转载 2018-08-25 23:28:27 · 303 阅读 · 0 评论 -
SPFA算法
SPFA算法是求解单源最短路径问题的一种算法,由理查德·贝尔曼(Richard Bellman) 和 莱斯特·福特 创立的。有时候这种算法也被称为 Moore-Bellman-Ford 算法,因为 Edward F. Moore 也为这个算法的发展做出了贡献。它的原理是对图进行V-1次松弛操作,得到所有可能的最短路径。其优于迪科斯彻算法的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高,高...原创 2018-08-25 23:16:53 · 3316 阅读 · 0 评论 -
Bellman-ford 算法
贝尔曼-福特算法,它的原理是对图进行V-1次松弛操作,得到所有可能的最短路径。其优于Dijkstra算法的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高,高达O(VE)。1. 算法流程给定图G(V, E)(其中V、E分别为图G的顶点集与边集),源点s,数组Distant[i]记录从源点s到顶点i的路径长度,初始化数组Distant[n]为, Distant[s]为0;以下操作...原创 2018-08-25 19:56:35 · 4764 阅读 · 0 评论 -
AC自动机算法详解
首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一。一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过。要搞懂AC自动机,先得有模式树(字典树)Trie和KMP模式匹配算法的基础知识。KMP算法是单模式串的字符匹配算法,AC自动机是多模式串的字符匹配算法。AC自动...原创 2018-10-07 20:10:33 · 295 阅读 · 0 评论 -
最短路径—Dijkstra算法
想必大家一定会Floyd了吧,Floyd只要暴力的三个for就可以出来,代码好背,也好理解,但缺点就是时间复杂度高是O(n³)。 于是今天就给大家带来一种时间复杂度是O(n²),的算法:Dijkstra(迪杰斯特拉)。 这个算法所求的是单源最短路,好比说你写好了Dijkstra的函数,那么只要输入点a的编号,就可算出图上每个点到这个点的距离。 我先上一组数据(这是无向图):...原创 2018-10-14 10:21:50 · 458 阅读 · 0 评论 -
素数筛
用筛法求素数的基本思想是:把从1开始的、某一范围内的正整数从小到大顺序排列, 1不是素数,首先把它筛掉。剩下的数中选择最小的数是素数,然后去掉它的倍数。依次类推,直到筛子为空时结束。 第一种:普通筛法。时间复杂度是O(nlogn),不足之处在于一个合数可能被筛选多次。void Prime ()//n是个数,标记为1则不是素数{ memset(tag,0,sizeof(tag)...原创 2018-10-07 20:33:16 · 276 阅读 · 0 评论 -
分解质因数
质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除(除0以外)的数称之为素数(质数);否则称为合数。根据算术基本定理,每一个比1大的整数,要么本身是一个质数,要么可以写成一系列质数的乘积;而且如果不考虑这些质数在乘积中的顺序,那么写出来的形式是唯一的。最小的质数是2。 质因数(或质因子)在数论里是指能整除给定正...原创 2018-10-07 21:00:30 · 1967 阅读 · 0 评论 -
对顶堆
处理动态中位数等问题,灵活运用了堆的性质,本质是维护两个堆。大根堆Q1:维护集合中较小值的部分的最大值。小根堆Q2:维护集合中较大值的部分的最小值。注意到两个堆中的元素各自是单调的,两个堆间也是单调的。也就是说,Q1中的任何一个元素都不大于Q2中的任何一个元素。那么假设高度为权值,两个堆可以形象化的表示成:如果两个堆的大小相差不超过1,较大的那个堆的堆顶必定是中位数(偶数个...原创 2018-10-16 12:10:55 · 433 阅读 · 0 评论 -
一套图 彻底明白了“时间复杂度”
写在前面: 这篇文章是在csdn公众号 程序人生中发布的。是我到目前为止所看到的关于时间复杂度介绍的最好的文章,简介 清晰 明了。所以拿来po出来 仅供学习交流,如侵则删。 正文: 时间复杂度的意义 究竟什么是时间复杂度呢?让我们来想象一个场景:某一天,小灰和大黄同时加入了一个公司......一天过后,小灰和大黄...转载 2018-11-15 14:10:35 · 990 阅读 · 0 评论 -
Dancing Links算法——求解精确覆盖问题
转载自:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1例如:如下的矩阵就包含了这样一个集合(第1、4、5行) 如何利用给定的矩阵求出相应的行的集合呢?我们采用回溯法 矩阵1: 先假定选择第1行,如下所示:...转载 2018-12-26 14:40:18 · 441 阅读 · 0 评论 -
舞蹈链(Dancing Links)算法求解数独
利用舞蹈链(Dancing Links)算法求解数独问题,实际上就是下面一个流程1、把数独问题转换为精确覆盖问题2、设计出数据矩阵3、用舞蹈链(Dancing Links)算法求解该精确覆盖问题4、把该精确覆盖问题的解转换为数独的解 首先看看数独问题(9*9的方格)的规则1、每个格子只能填一个数字2、每行每个数字只能填一遍3、每列每个数字只能填一遍4、每宫每...原创 2019-01-03 09:40:22 · 3066 阅读 · 0 评论 -
线段树
线段树是什么??线段树怎么写??如果你在考提高组前一天还在问这个问题,那么你会与一等奖失之交臂;如果你还在冲击普及组一等奖,那么这篇博客会浪费你人生中宝贵的5~20分钟。上面两句话显而易见,线段树这个数据结构是一个从萌新到正式OI选手的过渡,是一个非常重要的算法,也是一个对于萌新来说较难的算法。不得不说,我学习了这个算法5遍左右才有勇气写的这篇博客。但是,对于OI正式选手来说,线段树不...转载 2019-09-22 17:12:18 · 448 阅读 · 0 评论 -
康托展开和逆康托展开
简述康托展开是一个全排列到一个自然数的双射,常用于构建hash表时的空间压缩。设有n个数(1,2,3,4,…,n),可以有组成不同(n!种)的排列组合,康托展开表示的就是是当前排列组合在n个不同元素的全排列中的名次。原理X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中, a[i]为整数,并且0 <= a[i...原创 2018-08-21 22:33:38 · 3182 阅读 · 2 评论 -
A*算法
广度优先(BFS)和深度优先(DFS)搜索在谈A*之前,还是要先聊聊搜索算法中的老祖宗,深度和广度优先搜索算法。这两个算法,基本上各教科书都会有讲解,各种面试基本上也都会面到。不过为了讲清楚A*,我们还是先一起来看看他们吧。 深度优先搜索,用俗话说就是不见棺材不回头。算法会朝一个方向进发,直到遇到边界或者障碍物,才回溯。一般在实现的时候,我们采用递归的方式来进行,也可以采用模拟压栈的方...原创 2018-08-21 22:11:30 · 4061 阅读 · 1 评论 -
最小生成树-Prim算法和Kruskal算法
假设以下情景,有一块木板,板上钉上了一些钉子,这些钉子可以由一些细绳连接起来。假设每个钉子可以通过一根或者多根细绳连接起来,那么一定存在这样的情况,即用最少的细绳把所有钉子连接起来。更为实际的情景是这样的情况,在某地分布着N个村庄,现在需要在N个村庄之间修路,每个村庄之前的距离不同,问怎么修最短的路,将各个村庄连接起来。以上这些问题都可以归纳为最小生成树问题,用正式的表述方法描述为:给定一个无...原创 2018-08-16 20:50:06 · 659 阅读 · 0 评论 -
哈夫曼树+二叉堆
哈夫曼树的介绍Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树。定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。 这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答。(01) 路径和路径长度定义:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。若规定...原创 2018-08-07 11:17:50 · 1033 阅读 · 0 评论 -
树形结构 伸展树
除了拥有二叉查找树的性质之外,伸展树还具有的一个特点是:当某个节点被访问时,伸展树会通过旋转使该节点成为树根。这样做的好处是,下次要访问该节点时,能够迅速的访问到该节点。假设想要对一个二叉查找树执行一系列的查找操作。为了使整个查找时间更小,被查频率高的那些条目就应当经常处于靠近树根的位置。于是想到设计一个简单方法,在每次查找之后对树进行重构,把被查找的条目搬移到离树根近一些的地方。伸展树应运而生,...原创 2018-08-03 22:59:57 · 312 阅读 · 0 评论 -
树形结构 AVL树
它是最先发明的自平衡二叉查找树,也被称为高度平衡树。相比于"二叉查找树",它的特点是:AVL树中任何节点的两个子树的高度最大差别为1。有四种不平衡的情况会出现:AVL树的插入,单旋转的第一种情况---右旋:由上图可知:在插入之前树是一颗AVL树,而插入之后结点T的左右子树高度差的绝对值不再 < 1,此时AVL树的平衡性被破坏,我们要对其进行旋转。由上图可知我们是在结点T的左结点的左子...原创 2018-08-01 23:20:30 · 560 阅读 · 0 评论 -
树形结构 二叉查找树
对于任意结点,左子树的所有结点值小于自身的值,右子树的所有结点值大于自身的值;左右子树也是二叉查找树;#include<stdio.h>#include<stdlib.h>typedef struct BSTreeNode { int key;//关键值 BSTreeNode *left;//左孩子 BSTreeNode *right;//右孩...原创 2018-08-01 23:18:55 · 334 阅读 · 0 评论 -
线性结构
栈LIFO原则;只能在栈顶操作;C++的STL有stack;队列FIFO原则;队首进,队尾处;C++的STL有queue;PS:只摘录重点,STL源码不在此摘录,多读源码有益身心健康,Please RTFSC(Read The Fucking Source Code)!...原创 2018-08-01 23:17:03 · 287 阅读 · 0 评论 -
前言
这个分类下所有的东西都是挑重点写的,所以不要太在意一些细节,这个暑假本来想要好好搞acm的,结果两个网站还没结束,凉凉,怕不是数据结构部分都刷不完……不过我还是尽量手敲一边理解透彻,希望能坚持下来!ACM加油! 数据结构和算法线性结构栈队列树形结构二叉查找树AVL树伸展树红黑树哈夫曼树Trie最小生成树堆二叉堆左倾堆斜堆二顶堆...原创 2018-08-01 23:15:14 · 283 阅读 · 0 评论 -
红黑树(建议配合MIT的那个算法导论课程一起看)
将一个节点插入到红黑树中,需要执行哪些步骤呢?首先,将红黑树当作一颗二叉查找树,将节点插入;然后,将节点着色为红色;最后,通过旋转和重新着色等方法来修正该树,使之重新成为一颗红黑树。详细描述如下:第一步: 将红黑树当作一颗二叉查找树,将节点插入。 红黑树本身就是一颗二叉查找树,将节点插入后,该树仍然是一颗二叉查找树。也就意味着,树的键值仍然是有序的。此外,无论是左旋还是右旋,若旋...原创 2018-08-06 23:27:07 · 433 阅读 · 0 评论 -
二项堆
二项树的介绍二项树的定义二项堆是二项树的集合。在了解二项堆之前,先对二项树进行介绍。二项树是一种递归定义的有序树。它的递归定义如下:(01) 二项树B0只有一个结点;(02) 二项树Bk由两棵二项树B(k-1)组成的,其中一棵树是另一棵树根的最左孩子。如下图所示:上图的B0、B1、B2、B3、B4都是二项树。对比前面提到的二项树的定义:B0只有一个节点,B1由两个B0所组...原创 2018-08-10 23:06:51 · 427 阅读 · 0 评论 -
邻接矩阵有向图
和无向图的非常相似,只是反向不记录为1而已#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <string.h>#define MAX 100#define isLetter(a) ((((a)>='a')&&((a)<='...原创 2018-08-14 22:45:15 · 6488 阅读 · 0 评论 -
邻接表有向图
邻接表有向图的介绍邻接表有向图是指通过邻接表表示的有向图。上面的图G2包含了"A,B,C,D,E,F,G"共7个顶点,而且包含了"<A,B>,<B,C>,<B,E>,<B,F>,<C,E>,<D,C>,<E,B>,<E,D>,<F,原创 2018-08-14 22:47:20 · 12564 阅读 · 2 评论 -
左倾堆
左倾堆的介绍左倾堆(leftist tree 或 leftist heap),又被成为左偏树、左偏堆,最左堆等。它和二叉堆一样,都是优先队列实现方式。当优先队列中涉及到"对两个优先队列进行合并"的问题时,二叉堆的效率就无法令人满意了,而本文介绍的左倾堆,则可以很好地解决这类问题。 左倾堆的定义左倾堆是一棵二叉树,它的节点除了和二叉树的节点一样具有左右子树指针外,还有两个属性:键值...原创 2018-08-07 21:42:32 · 1225 阅读 · 0 评论 -
Trie树
1、基本概念 字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种。 2、基本性质根节点不包含字符,除根节点外的每一个子节点都包含一个字符 从根节点到某一节点。路径上经过的字符连接起来,就是该节点对应的字符串 每个节点的所有子节点包含的字符都不相同 3、应用场景 典型应用是用于统计,排序和保存大量的字符串(不仅限于字符串),经常被搜索引擎...原创 2018-08-16 19:19:42 · 237 阅读 · 0 评论 -
Hash算法
哈希表(Hash Table)原理及其实现原理介绍哈希表(Hash table,也叫散列表), 是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。哈希表hash table(key,value) 的做法其实很简单,就是把Key通过一个固定的算法函...原创 2018-08-13 23:13:57 · 412 阅读 · 0 评论 -
邻接表无向图
邻接表无向图的介绍邻接表无向图是指通过邻接表表示的无向图。#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <string.h>#define MAX 100#define isLetter(a) ((((a)>='a')&&am...原创 2018-08-13 20:55:38 · 1267 阅读 · 0 评论 -
邻接矩阵无向图
邻接矩阵无向图的介绍邻接矩阵无向图是指通过邻接矩阵表示的无向图。上面的图G1包含了"A,B,C,D,E,F,G"共7个顶点,而且包含了"(A,C),(A,D),(A,F),(B,C),(C,D),(E,G),(F,G)"共7条边。由于这是无向图,所以边(A,C)和边(C,A)是同一条边;这里列举边时,是按照字母先后顺序列举的。上图右边的矩阵是G1在内存中的邻接矩阵示意图。A[i][...原创 2018-08-13 18:20:19 · 16060 阅读 · 0 评论 -
DFS和BFS(搜索的方向是一种可能性,不重不漏就好)
图的深度优先搜索(Depth First Search),和树的先序遍历比较类似。它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。显然,深度优先搜索是...原创 2018-08-08 23:34:57 · 547 阅读 · 0 评论 -
拓扑排序
拓扑排序介绍拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列。这样说,可能理解起来比较抽象。下面通过简单的例子进行说明! 例如,一个项目包括A、B、C、D四个子部分来完成,并且A依赖于B和D,C依赖于D。现在要制定一个计划,写出A、B、C、D的执行顺序。这时,就可以利用到拓扑排...原创 2018-08-15 15:42:08 · 1068 阅读 · 0 评论 -
图的理论基础
图的基本概念1. 图的定义定义:图(graph)是由一些点(vertex)和这些点之间的连线(edge)所组成的;其中,点通常被成为"顶点(vertex)",而点与点之间的连线则被成为"边或弧"(edege)。通常记为,G=(V,E)。2. 图的种类根据边是否有方向,将图可以划分为:无向图和有向图。2.1 无向图上面的图G0是无向图,无向图的所有的边都是不区分方向的。G...原创 2018-08-12 21:43:25 · 286 阅读 · 0 评论