实用算法实践
文章平均质量分 88
存储李希
毕业于北京大学,曾于国家并行计算机工程技术研究中心就读并工作,现于DDN Storage公司从事分布式文件系统研发工作,主攻Lustre文件系统。开源文件系统MTFS的作者。
展开
-
实用算法实践-第1篇 排序
1.1 选择排序许多排序算法比选择排序快多了,但是选择排序能够将排序的交换次数降到最少,这是它比冒泡排序的优点之所在。通过下面这个实例就可以深刻认识这一点。1.1.1 实例PKU JudgeOnline, 1674, Sorting by Swapping.1.2 库函数的应用快速排序函数qsort()非常好用,下面就是一些应用例子。据说,STL的sor原创 2011-10-09 19:15:37 · 1535 阅读 · 0 评论 -
实用算法实现-第 17 篇 强连通分支
求强连通分量的著名算法:Kosaraju算法,Gabow算法和Tarjan算法。其中Kosaraju算法要对原图和逆图都进行一次DFS,而另外两种算法只要进行一次DFS即可。[i]文是介绍Gabow算法的论文。17.1 Kosaraju算法Kosaraju算法虽然要进行两次DFS,但是复杂度仍然是O(V+E),而且比较容易理解。17.1.1 实例PKU JudgeOnli原创 2011-10-25 23:38:48 · 1291 阅读 · 0 评论 -
实用算法实现-第 18 欧拉回路
18.1 欧拉回路存在性的判断欧拉回路问题可以分为无向图中的欧拉回路和欧拉通路,有向图中的欧拉回路和欧拉通路。这几个问题大抵相像。有向欧拉回路有:定理:假设有像多重图D有性质:当忽略有向边上的方向时,得到的图是连通的,那么D有有向欧拉回路当且仅当D的每个顶点的入度和出度相等。类似的,对有向欧拉通路有:定理:D有有向欧拉通路,当且仅当除两个不同顶点B和C之外,D的其它顶点的原创 2011-10-26 23:20:02 · 4754 阅读 · 4 评论 -
实用算法实现-第 19 第 最小生成树
19.1 Prim算法《算法导论》中,Prim算法的伪代码如下:MST-PRIM(G, w, r)1 for each u ∈ V[G]2 do key[u] ← NIL3 ∏[u] ← NIL4 key [r] ← 05 Q ← V[G]6 while Q ≠ Ф7 do u ← EXTRACT-MIN(Q)8 for each v ∈ Adj[u]9原创 2011-11-02 23:45:56 · 1588 阅读 · 0 评论 -
实用算法实现-第 20 篇 单源最短路径
20.1 Dijktra算法Dijktra算法适用于有向图上带权的单源最短路径,但是要求所有边的权值非负。所以它一方面比Ford性能好,一方面又没有Ford算法的通用性。对比Dijktra算法和Prim算法,可以发现两者的相似之处。20.1.1 实例PKU JudgeOnline, 3268, Silver Cow Party.20.1.2 问题描述一只母原创 2011-11-03 23:22:53 · 1007 阅读 · 0 评论 -
实用算法实现-第 21 篇 每对顶点间的最短路径
21.1 每对顶点间最短路径与矩阵乘法 考虑矩阵乘法D*D,有:d’’(i, j) = ∑(d’ (i, k) * d’ (k, j)) 考虑有向图每对顶点间的距离邻接矩阵。w(i, j)为由i点都j点的路径距离。故此有矩阵W的i行向量为i到点集合{j, 1≤j≤n}的距离。而矩阵W的j列向量为点集合{i, 1≤i≤n}到j的距离。 要求最短路径,可以先考虑原创 2012-01-09 22:28:09 · 1188 阅读 · 0 评论 -
实用算法实践-第 22 篇 字符串匹配
22.1 Knuth-Morris-Pratt算法22.1.1 实例PKU JudgeOnline, 3461, Oulipo.22.1.2 问题描述求字符串在另外一个字符串中出现了几次。22.1.3 输入3BAPCBAPCAZAAZAZAZAVERDIAVERDXIVYERDIAN22.1.4 输出1302原创 2012-01-10 22:53:12 · 840 阅读 · 0 评论 -
实用算法实现-第 23 篇 最大流
23.1 Ford-Fullkerson方法使用BFS来实现Ford-Fullkerson方法中的找增广路径的算法称为Edmods-Karp算法。Edmods-Karp算法是最短增广路算法,因为实用BFS找到的增广路径是所有可能的增广路径中最短的路径。它的复杂度是O(VE2),其中V是结点数,E是有向边数。如果用使用DFS代替BFS,则Ford-Fullkerson方法退化成一原创 2012-01-14 23:16:28 · 2073 阅读 · 0 评论 -
实用算法实现-第 24 篇 高精度整数运算
24.1 高精度整数加法24.1.1 实例PKU JudgeOnline, 1503, Integer Inquiry.24.1.2 问题描述给定一组超长的正整数(100位),求出它们的和。24.1.3 输入12345678901234567890123456789012345678901234567890123456789012345678901原创 2012-01-15 23:24:09 · 1056 阅读 · 0 评论 -
实用算法实现-第 25 篇 最大公约数
最大公约数有经典算法Euclid算法可以求出。而对于正整数a、b,若将它们的最大公约数表示为gcd(a, b),最小公倍数表示为lcm(a, b),那么有公式:a • b = gcd(a, b) • lcm(a, b)。由这个公式,可以求得两个数的最小公倍数。25.1 Euclid算法int Euclid(int a, intb){/*欧几里德算法GCD递归定理:对任意原创 2012-01-24 21:42:27 · 799 阅读 · 2 评论 -
实用算法实现-第 26 篇 模运算
26.1 模运算的基本性质《算法导论》中提到,模加法和模乘法是两个有限可交换群。由于模运算的基本性质,故此可以对模乘运算进行分治。26.2 实例PKU JudgeOnline, 1811, Prime Test.PKU JudgeOnline, 3070, Fibonacci.本文章欢迎转载,请保留原始博客链接http://blog.csdn.net/fsd原创 2012-01-24 21:42:41 · 1208 阅读 · 0 评论 -
实用算法实现-第 27 篇 中国余数定理
27.1 中国余数定理定理:对任意n > 1,如果gcd(a, n) = 1,则方程a • x ≡ 1(mod n)对模n有唯一解,否则方程无解。若方程有解,x可以表示为(a^-1) mod n,x可以由欧几里德算法的扩广形式求出。设n1, n2, ..., nk两两互质,n = n1• n2 • ... • nk定义:mi = n1• n2 • ... • ni-1 • ni+原创 2012-01-24 21:49:30 · 2906 阅读 · 0 评论 -
实用算法实践-第 31 篇 博弈游戏
31.1 Bash博弈只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。很容易想到当n%(m+1)这个游戏还可以有一种变相的玩法:两个人轮流报数,每次至少报一个,最多报十个,谁能报到100者胜。31.2 Wythoff博弈有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后原创 2012-02-14 22:18:03 · 1779 阅读 · 0 评论 -
实用算法实践-第 32 篇 其它
32.1 平衡三进制 PKU JudgeOnline, 1702, Eva'sBalance是一个平衡三进制问题的实例。将一个某进制数转换为平衡三进制数的方法为:先转化为用0,1,2表示的3进制,然后通过“借位”转换。也即: 若对应的系数为2,则变为-1,高一位+1。 若对应的系数为3,则变为0,高一位+1。 为0或1时不变原创 2012-02-29 00:22:07 · 1668 阅读 · 0 评论 -
实用算法实践-第 30 篇 组合数学
30.1 Ctalan数PKU JudgeOnline, 1095, Trees Made to Order.30.2 Fibonacci数Fibonacci数列的定义如下:f(n) = f(n - 1) + f(n - 2) (n >= 3)f(1) = 1, f(2) = 2f(0)可定义为1。用归纳法可以证明性质:f(n + m) = f(m -原创 2012-02-08 23:38:08 · 1422 阅读 · 0 评论 -
实用算法实践-第 29 篇 计算几何学
29.1 最近点对“最近”是指通常意义上的欧几里德距离。《算法导论》中对这个问题进行了介绍。[i]问对于经典的分治法求最近点对有深入的介绍和详尽的伪代码。29.1.1 实例PKU JudgeOnline, 3714, Raid.29.1.2 问题描述给定n个岗位和n个战士的坐标(0 ≤ X ≤1000000000, 0 ≤ Y ≤ 1000000000)。问这些战原创 2012-02-07 19:39:18 · 1905 阅读 · 0 评论 -
实用算法实现-第 16 篇 拓扑排序
16.1 拓扑排序拓扑排序的本质是由某集合上的一个偏序得到该集合上的一个全序。16.1.1 实例PKU JudgeOnline, 1094, Sorting It All Out. 16.1.2 问题描述给出类似A注意:当拓扑排序不唯一(当然也就不确定)的时候 还要判断是否有环。注意:如果前几条不等式可以确定一个序列,那么后面的的都要被忽略,即使加上它们会原创 2011-10-24 23:19:18 · 783 阅读 · 0 评论 -
实用算法实现-第 15 篇 对抗搜索
《人工智能,一种现代方法》对于对抗搜索的介绍非常好。15.1 极小值极大值策略极大值极小值策略是一种最优策略。当对手不犯错误时,最优策略能够导致至少不比其它任何其它策略差的结果。需要注意的是,最优策略针对的是最优化对手:如果使用极大值极小值策略对付非最优化对手,可能没有使用其它策略好,但是使用那些策略对付最优化对手必定要比极大值极小值策略差。极小值极大值策略是指存在两个最优化的博原创 2011-10-23 23:39:08 · 4652 阅读 · 0 评论 -
实用算法实现-第 14 篇 启发式搜索
14.1 A*搜索A*(A star)算法是一种很好的树搜索策略,在许多人工智能的书籍中有所介绍。比如《人工智能,一种现代方法》和《人工智能,复杂问题求解的结构和策略》。[i]文介绍到,A*算法使用估价函数F(N)来估算从初始状态S到当前状态N,再到目标状态T需要的最小步数。有公式:F(N) = G(N) + H(N)其中,G(N)是起始状态S到当前状态的实际代价G(N),它原创 2011-10-23 00:15:58 · 7255 阅读 · 0 评论 -
实用算法实践-第 2 篇 有序数组的二分查找
2.1 有序数组的二分查找有序数组的二分查找就是利用数组的有序性,找到满足条件的最大(或者最小)下标。因为由于有序性,所以如果下标A不满足条件,那么比A小(或者大)的所有下标都不满足条件,故此可以使用二分查找。二分的思想还用在其他的地方,都是在具有类似有序的一组元素中找出符合条件的最大(或最小)下标的地方。例如答案的二分。2.1.1 程序int Correspond(原创 2011-10-10 19:08:35 · 1179 阅读 · 0 评论 -
实用算法实践-第 3 篇 堆排序
虽然堆排序算法是一个很漂亮的算法,但是在实际中,快排序的一个好的实现往往优于堆排序。尽管这样堆数据结构还有很大的用处,例如优先级队列。3.1 最小堆下面的程序就是按照《算法导论》最小堆的优先级队列的实现,修改几个小于号(大于号)可以轻易地将最小堆变成最大堆。最小堆的一个用法实例是在Huffman编码中。3.1.1 最小堆的优先级队列程序#include #inc原创 2011-10-10 19:09:05 · 881 阅读 · 0 评论 -
实用算法实践-第 4 篇 散列表
4.1 直接寻址表当关键字的全域比较小时,直接寻址时一种简单而有效的技术。4.1.1 实例PKU JudgeOnline, 1200, Crazy Search.4.1.2 问题描述给定一个有NC个不同字符的字符串,求出其长度为N的子字符串的个数。例如字符串“daababac”有5个长度为3的子字符串:“daa”、“aab”、“aba”、“bab”、“bac”。原创 2011-10-11 10:28:21 · 768 阅读 · 0 评论 -
实用算法实现-第 5 篇 二分查找树
5.1 二分查找树算法《算法导论》中,二分查找树的伪代码如下:ITERATIVE-TREE-SEARCH(x,k)1 while x ≠ NIL and k ≠ key[x]2 do if k 3 thenx ← left[x]4 elsex ← right[x]5 return xTREE-INSER原创 2011-10-12 12:26:24 · 1204 阅读 · 0 评论 -
实用算法实现-第6篇 线段树
6.1 线段树简介线段树的定义如下: 一棵二叉树,记为T (a,b),参数a,b表示该结点表示区间[a,b]。区间的长度b-a记为L。递归定义T[a,b]: 若L>1 :[a, (a+b) div 2]为 T的左儿子 [(a+b)div 2,b]为T的右儿子。 若L=1 :T为一个叶子原创 2011-10-13 21:13:22 · 3276 阅读 · 0 评论 -
实用算法实现-第 7 篇 Trie树
Trie,又称单词查找树,是一种树形结构,用于保存大量的字符串。它的优点是:利用字符串的公共前缀来节约存储空间。它有3个基本性质:1. 根结点不包含字符,除根结点外每一个结点都只包含一个字符。2. 从根结点到某一结点,路径上经过的字符连接起来,为该结点对应的字符串。3. 每个结点的所有子结点包含的字符都不相同。7.1 Trie树7.1.1 实例PKU JudgeO原创 2011-10-15 00:59:33 · 1452 阅读 · 1 评论 -
实用算法实现-第8篇 后缀树和后缀数组 [1简介]
8.1 后缀树一棵后缀树包含一个指定文本的所有后缀,对于在一个长度为N的文本中查找一个长度为M的子字符串,一个后缀树仅仅需要M次比较,而这个比较次数是查找该字符串所需要的最小比较次数。后缀树有以下特征:一条边可以表示文本的任何非空子串,每个非终端节点,除了根节点,必须至少有两个孩子边,兄弟边表示的子串必须开始于不同的字符。ababa所对应的后缀树如下所示:后缀树可以解原创 2011-10-15 11:50:24 · 4398 阅读 · 0 评论 -
实用算法实现-第 8 篇 后缀树和后缀数组 [2 最长公共子串]
8.3 最长公共子串求N个串的最长公共子串,可以转化为求一些后缀的最长公共前缀的最大值,这些后缀应分属于N个串。设N个串分别为S1,S2,S3,…,SN。具体方法如下:1. 建立字符串S,使得S = S1[P1]S2[P2]S3…SN-1[PN-1]SN。其中P1,P2,…,PN-1应为不同的N - 1个不在字符集中的字符,作为分隔符。插入分隔符的目的是为了防止S的后缀的公共前缀原创 2011-10-16 00:01:48 · 2891 阅读 · 0 评论 -
实用算法实现-第 8 篇 后缀树和后缀数组 [3 两个字符串的最长公共子串]
8.4 两个字符串的最长公共子串两个串的最长公共字串是相对于多个串要简单一点,不需要二分A。只需要判断相邻两个Height是不是分属两个字符串即可。8.4.1 实例PKU JudgeOnline, 2774, Long Long Message.8.4.2 问题描述给两个小写ASCII字母组成的字符串,求出它们最大公共子串的长度。相比PKUJudgeOnlin原创 2011-10-16 12:56:24 · 1376 阅读 · 0 评论 -
实用算法实现-第 8 篇 后缀树和后缀数组 [4 最长回文子串]
8.5 最长回文子串定义字符串S的逆序为S’,有S’[i]=S[n - i - 1](0 ≤ i 定义Suffix(S, i)为S以S[i]开头且包含S[i]的后缀字符串。定义Prefix(S, i)为S以S[i]结尾且包含S[i]的后缀字符串。令n = Len(S)可知有如下性质:1. Len(S’) = Len(S) = n;2. Len(Suffix(S,原创 2011-10-16 13:31:57 · 2010 阅读 · 0 评论 -
实用算法实现-第 9 篇 RMQ问题
9.1 RMQ问题RMQ(Range Minimum/Maximum Query)问题,就是对于给定数组,在其下标范围[i, j]内给出的最小值(或最大值,下文都称最小值)的问题。RMQ和LCA问题可以互相转化,一个对RMQ和LCA问题的总结如下表[i]: 算法处理方式复杂度备注转化算法原创 2011-10-17 08:33:28 · 1023 阅读 · 0 评论 -
实用算法实现-第 10 篇 动态规划
10.1 动态规划10.1.1 实例PKU JudgeOnline, 1160, Post Office.10.1.2 问题描述 一条直线上分布着V个村庄。要在这些村庄中的某些村庄里建一共P个邮局,使得村庄到离它最近的邮局的距离之和最小。输出这个的最小距离之和。10.1.3 输入10512 3 6 7 9 11 22 44 5010原创 2011-10-18 15:17:28 · 1030 阅读 · 0 评论 -
实用算法实现-第 11 篇 贪心算法
11.1 Huffman编码Huffman设计了一个可以用来构造一种称为Huffman编码的最优前缀码的贪心算法。11.1.1 实例PKU JudgeOnline, 1521, Entropy.11.1.2 问题描述给定一组ASCII码组成的字符串,求用Huffman编码该字符串所需的长度,及采用该编码带来的压缩比。11.1.3 输入AAAAABCD原创 2011-10-20 12:17:19 · 909 阅读 · 0 评论 -
实用算法实现-第12篇 不相交集合(并查集)
12.1 不加按秩合并启发式的并查集并查集可以进行两方面的启发式,一种是按秩合并,也就是使得包含较少结点的树的根指向包含较多结点的树的根。另一种是路径压缩,也就是使得查找路径上的每个结点都直接指向根结点。但是有些问题只有使用不加按秩合并启发式的并查集才能够解决,因为按秩合并意味着不能够手动控制集合的合并方向。12.1.1 实例PKU JudgeOnline, 1182,原创 2011-10-21 12:18:11 · 1316 阅读 · 0 评论 -
实用算法实现-第13篇 搜索(盲目搜索)
在人工智能中,盲目搜索是相对于启发式搜索来说的。13.1 广度优先搜索《算法导论》中,广度优先(Breadth-First)搜索树的伪代码如下:BFS(G,s)1 for each vertex u ∈ V[G] - {s}2 docolor[u] ← WHITE3 d[u] ← ∞4 ∏[u] ← NIL原创 2011-10-22 01:17:13 · 10848 阅读 · 0 评论 -
实用算法实践-第 28 篇 素数判别
28.1 朴素的素数判别bool isPrime(__long n){ //简单的判断素数的确定性算法 __long i; if(n == 2|| n == 3) return true; if(n % 2 ==0) return false; for(i = 3;i < (__long)sqrt((原创 2012-02-04 19:35:23 · 1301 阅读 · 0 评论