算法总结
文章平均质量分 87
飘过的小牛
不停成长才会洞悉成功的奥妙,fighting!
展开
-
KMP算法详讲
一. 简单匹配算法先来看一个简单匹配算法的函数:int Index_BF ( char S [ ], char T [ ], int pos ){/* 若串 S 中从第pos(S 的下标0≤pos<StrLength(S))个字符起存在和串 T 相同的子串,则称匹配成功,返回第一个这样的子串在串 S 中的下标,否则返回 -1 */int i = pos, j = 0;w原创 2011-11-11 19:50:15 · 3738 阅读 · 3 评论 -
归并排序
一个归并排序的例子:对一个随机点的链表进行排序归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。算法时间复杂度位O(nlogn).归并操作:归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。算法描述:1.原创 2011-12-14 17:23:59 · 1295 阅读 · 1 评论 -
Kuhn-Munkres算法
死磕了2天的KM,总算理解了七八分了。。。。下面是网上各种东西的杂糅+自己的说明,死磕应该能看懂。KM算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转化为求完备匹配的问题的。设顶点Xi的顶标为A[i],顶点Yi的顶标为B[i],顶点Xi与Yj之间的边权为w[i,j]。在算法执行过程中的任一时刻,对于任一条边(i,j), A[i]+B[j]>=w[i,j]始终成立。K原创 2012-01-02 22:53:02 · 22413 阅读 · 10 评论 -
Floyd算法详讲
正如我们所知道的,Floyd算法用于求最短路径。Floyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3)。Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B。所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点X,我们检查Dis(AX) +原创 2011-09-13 21:54:13 · 16295 阅读 · 4 评论 -
快速排序
快速排序是分治策略的一个应用。算法思想就是基准元素的划分,这点可以参考书上的分析。主要给出快速排序算法的分析:快速排序算法的时间主要耗费在划分操作上,并与划分是否平衡密切相关。对于长度为n的待排序序列,一次划分算法Partition需要堆整个待排序序列扫描一遍,其所需要的计算时间显然为O(n)。下面从三种情况来讨论一下快速排序算法的时间复杂度。(1)最坏时间复杂度最坏情况是原创 2012-02-23 10:26:14 · 2213 阅读 · 3 评论 -
堆排序
参考文章有很多,推荐:http://www.wutianqi.com/?p=1820注:堆排序不是一种稳定排序。堆排序方法对记录数较稍等文件并不值得提倡,但对n较大的文件还是很有效的。因为其运行时间主要耗费在建初始堆和调整建新堆时进行的反复“筛选”上。对深度为k的堆,筛选算法中进行的关键字比较次数之多为2(k-1)次,则在建含n个元素,深度为h的堆时,总共进行的关键字比较次数不超过原创 2012-02-22 18:22:54 · 2012 阅读 · 0 评论 -
寻找主元素
如果一个数组A[1..n]中超过半数的元素都相同时,该数组被称为含有主元素。算法思想:利用快速排序的思想,如果这个数组存在主元素,则它一定为排序后的中位数。但问题是,我们要设计O(n)算法,我们知道,排序的最优时间复杂度是O(nlogn),所以我们需要借助其他的方法来完成这个问题。我们可以想到快速排序,当我们调整基准元素时,如果基准元素到达n/2,则说明左边都比它小,右边都比它原创 2012-03-09 09:00:24 · 4807 阅读 · 4 评论 -
RMQ (Range Minimum/Maximum Query)算法
1. 概述RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j当然,该问题也可以用线段树(也叫区间树)解决,算法复杂度为:O(N)~O(logN),这里我们暂不介绍。2.RMQ算法对于该问题,最容易想到的解决方案是遍历,复杂度是O(n)。但当数据量非常大原创 2011-07-22 08:24:26 · 14949 阅读 · 7 评论 -
二分查找
第一步:从伪代码到具体的C语言代码一般版本:int binarysearch(int arr[], int n, int key){ int low = 0, high = n; while(low < high) { int mid = low + (high - low) / 2; if(arr[mid] == key) { cout<<"fad";原创 2011-05-06 21:51:00 · 1355 阅读 · 0 评论 -
二分图最大匹配的König定理-最小点集覆盖【Matrix67】
König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数。如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖所有的边。比如,下面这个图中的最大匹配和最小点覆盖已分别用蓝色和红色标注。它们都等于3。转载 2011-12-03 10:04:21 · 5120 阅读 · 0 评论 -
二分图最大匹配—匈牙利算法
二分图:又叫二部图,图G中顶点集V可以分成互不相交的子集(X,Y),并且图中的每一条边所关联的点分别属于两个不同的顶点集,则图G叫二分图。(不含奇环)二分图的匹配:给定一个二分图G的子图M,M的边集中任意两条边都不依附于同一个顶点(点单独配对),则称M是一个匹配。二分图的最大匹配:边数最大的一个匹配就是二分图的最大匹配。看上去二分图匹配好像没有什么用途,但以下三个定理会有大原创 2011-11-29 13:33:50 · 2480 阅读 · 0 评论 -
AC自动机算法
AC自动机简介: 首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一。一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过。要搞懂AC自动机,先得有字典树Trie和KMP模式匹配算法的基础知识。KMP算法是单模式串的字符匹配算法,AC自动机是多模式串的字符匹配算法。原创 2011-11-23 09:04:50 · 97981 阅读 · 4 评论 -
高效素数打表
大家所知的素数打表时间复杂度几乎都是n2。就是这种:void init_prime(){ int i, j; for(i = 2;i <= sqrt(1000002.0); ++i) { if(!prime[i]) for(j = i * i; j < 1000002; j += i) prime[j] = 1; } j = 0; for(i = 2;i原创 2011-11-15 15:07:29 · 14673 阅读 · 4 评论 -
Prime算法
普利姆(Prime)算法(只与顶点相关) 算法描述:普利姆算法求最小生成树时候,和边数无关,只和定点的数量相关,所以适合求稠密网的最小生成树,时间复杂度为O(n*n)。算法过程:1.将一个图的顶点分为两部分,一部分是最小生成树中的结点(A集合),另一部分是未处理的结点(B集合)。2.首先选择一个结点,将这个结点加入A中,然后,对集合A中的顶点遍历,找原创 2011-08-15 18:05:10 · 16745 阅读 · 4 评论 -
Kruskal算法
克鲁斯卡尔(Kruskal)算法(只与边相关)算法描述:克鲁斯卡尔算法需要对图的边进行访问,所以克鲁斯卡尔算法的时间复杂度只和边又关系,可以证明其时间复杂度为O(eloge)。算法过程:1.将图各边按照权值进行排序2.将图遍历一次,找出权值最小的边,(条件:此次找出的边不能和已加入最小生成树集合的边构成环),若符合条件,则加入最小生成树的集合中。不符合条原创 2011-08-15 17:59:21 · 33777 阅读 · 10 评论 -
弗罗莱(Fleury)算法,求欧拉(Euler)通路/回路
1、基本概念:(1)定义欧拉通路 (欧拉迹)—通过图中每条边一次且仅一次,并且过每一顶点的通路。欧拉回路 (欧拉闭迹)—通过图中每条边一次且仅一次,并且过每一顶点的回路。欧拉图—存在欧拉回路的图。欧拉图就是从一顶出发每条边恰通过一次又能回到出发顶点的那种图,即不重复的行遍所有的边再回到出发点。通路和回路-称vie1e2…envj为一条从 vi到 vj且长度为n的通路,其中长度是原创 2011-06-16 18:01:00 · 11703 阅读 · 1 评论 -
字典树
字典树,顾名思义,就是一种对字母等字符串进行处理的一种特殊数据结构。说白了,就是二十六叉树。定义一个头指针,每次从头指针开始操作。有两种常用的操作:1.查询某个字符串的出现次数。每个节点的count置为0,直到这个字符串结束,在末尾处count++.这样,就记录了该字符串的出现次数。2.查询某个字符串特定序列出现的次数。每个节点的count初始化为0,当读入一个字符,则coun原创 2011-08-17 17:06:20 · 1755 阅读 · 0 评论 -
树状数组
已知数组a[],元素个数为n,现在更改a中的元素,要求得新的a数组中i到j区间内的和(1思考:对于这个问题,我们可以暴力地来解决,从a[i]一直累加到a[j],最坏的情况下复杂度为O(n),对于m次change&querry,合起来的复杂度为O(m*n),在n或m很大的情况下,这样的复杂度是让人无法忍受的.另外,如果没有元素的变更,我们完全可以存储sum[1,k](k=1,2,……),然后原创 2011-07-21 17:01:47 · 1223 阅读 · 0 评论 -
Dijkstra+Heap+前向星存图
一切尽在代码中。。。。。。。。/* dijkstra + heap,时间复杂度: O((n + e)log(n)). 对于稠密图来说,仍然是dij+heap快,而且越稠密越快! 用前向星来存图,空间复杂度为: O(m). 更新时间: 2011.09.22*/#include #include #include #include #include原创 2011-09-22 21:30:01 · 3413 阅读 · 2 评论 -
链栈实现括号匹配
//括号匹配//利用栈的操作思想,实现括号匹配的检验。如输入3*{2+[2*5/(2+9)]},则括号匹配//正确,但如果输入3*(2+6/[2*9)],则括号匹配失败。//优先级说明://()优先级最高,里面不能嵌套任何其他括号(包括小括号);//[]优先级其次,里面只能嵌套小括号//{}优先级最低,里面可以嵌套大括号和小括号 #include #include #includ原创 2011-08-09 16:45:28 · 4933 阅读 · 1 评论 -
拓扑排序
什么是拓扑排序?简单的说,就是由某个集合上的一个偏序序列得到该集合上的一个全序序列,这个操作称之为拓扑排序。那么,我们首先来回顾一下离散数学中的关于偏序和全序的定义:若集合X上的关系R是自反的,反对称的和传递的,则称R是集合X上的偏序关系。设R是集合X上的pain徐,如果对每个x,y输入X,必有xRy或者yRx,则称R是集合X上的全序关系。举个简单的例子说明什么是拓扑排序。现在原创 2011-10-31 13:07:32 · 2281 阅读 · 1 评论 -
Bellman-Ford算法详讲
Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的。这时候,就需要使用其他的算法来求解最短路径,Bellman-Ford算法就是其中最常用的一个。该算法由美国数学家理查德•贝尔曼(Richard Bellman, 动态规划的提出者)和小莱斯特•福特(Lester Ford)发明。适转载 2011-09-19 21:56:40 · 77442 阅读 · 8 评论