算法
文章平均质量分 61
whitejava2
这个作者很懒,什么都没留下…
展开
-
算法8-6:最小生成树研究现状
目前已经介绍了Kruskal和Prim算法,他们的复杂度一个是E logE一个是E logV,那么有没有复杂度为E的算法呢?理论上是可能的,但是目前还没有发现该算法。下图是最小生成树算法的发展过程。从图中可以看到复杂度越來越接近E。最小生成树的应用欧几里德最小生成树问题描述:给定一系列点的坐标,求包含所有点原创 2014-06-20 19:48:04 · 1730 阅读 · 0 评论 -
普林斯顿公开课 算法1-2:观察
这章通过一个简单的例子,详细说明算法分析的步骤。算法问题给定N个不同的整数,从中任意取出三个整数。请问有几种情况,使得取出的3个整数之和为0?解法可以使用暴力算法,代码如下:123456789for(int i=0;原创 2014-05-30 19:54:09 · 2474 阅读 · 0 评论 -
普林斯顿公开课 算法1-3:数学模型
本节主要通过建立数学模型,来计算算法的运行时间。公式算法的运行时间=所有操作的开销乘以操作的次数之和开销下表展示了各种操作所需要的时间(单位:纳秒)整数加法 2.1整数乘法 2.4整数除法 5.4浮点加法 4.6浮点乘法 4.2浮点除法 13.5sin 91.3原创 2014-05-30 19:55:02 · 2176 阅读 · 0 评论 -
普林斯顿公开课 算法1-5:算法理论
本节主要讲解的是算法的复杂度。算法性能算法的性能分为三种:最佳情况:计算时间最短的情况最差情况:计算时间最长的情况平均情况:随机输入的期望开销以二分查找为例最佳情况是1,因为第一次就有可能找到需要找的整数。最差情况是logN平均情况是logN算法复杂度原创 2014-05-31 20:33:16 · 2172 阅读 · 0 评论 -
普林斯顿公开课 算法1-6:内存
讲完了算法的运行时间,现在讲一下关于算法的内存占用率。内存单位在计算机中,内存是通过字节来表示的,一个字节表示8个位。1KB是2^10字节。数据类型占用的内存在32位系统中,一个指针占用4个字节。在64位系统中一个指针占用8个字节。本课程中使用64位机器,一个指针占用8字节。基本数据类型原创 2014-05-31 20:34:02 · 2225 阅读 · 0 评论 -
普林斯顿公开课 算法1-8:并查集 快速查找
本节讲的是并查集的第一种实现方法,这种方法查找操作开销很小而合并操作开销比较大。数据结构假设有N个节点,那么该算法的数据结构就是一个包含N个整数的数组id[]。判断操作判断节点p和节点q是否相连就是判断id[p]和id[q]的值是否一致。合并操作合并节点p和节点q就是将id数组中所有的id[原创 2014-05-31 20:36:56 · 1969 阅读 · 0 评论 -
普林斯顿公开课 算法1-9:并查集-快速合并
本节讲的是并查集的另外一种实现方法。这种方法的合并操作开销很小,但是查找操作开销很大。数据结构这种算法的数据结构和快速查找方法的数据结构是一样的,也是N个整数组成的数组。数组中每个元素id[i]的含义是指i的上级是id[i]。根节点一个节点的根节点就是id[id[id[...id[i]....]]],一直循原创 2014-05-31 20:37:50 · 1806 阅读 · 0 评论 -
普林斯顿公开课 算法1-7:并查集基本概念
本节讲的是并查集的基本概念。算法的开发步骤对问题进行数学建模寻找一个能够解决问题的算法运行算法检测速度和内存是否符合要求如果达不到要求,找出原因寻找一种方法来解决问题循环步骤,直到满意为止以上就是算法开发比较科学的方法。算法开发完成之后需要进行数学分析。并查集问题原创 2014-05-31 20:35:55 · 1888 阅读 · 0 评论 -
算法7-1:图论简介
无向图无向图由顶点和边组成,边用于连接两个顶点。下面这张地图就是无向图的一个例子。OPTE工程OPTE工程的目标就是绘制整个互联网的样子。下图是2010年的互联网。互联网也是无向图的一个例子。这张图是用LGL软件进行绘制的。有兴趣的同学可以研究一下:http://www.opte.org/原创 2014-06-16 19:07:06 · 1111 阅读 · 0 评论 -
通俗解释什么是傅立叶变换
大家一定见过下面这种声音的波形图吧。大家也一定见过播放音乐时跳动的条形图吧,它将声音分成多个频段,可以显示每个频段的音量。下面这种频谱图和上图也是类似,颜色亮的地方表示某个频率的音量大。亮点越高表示声音的频率越大,听起来越感觉尖锐。波形图转换成频谱图的过程中就用到了傅立叶变换。简原创 2014-05-30 19:51:05 · 2647 阅读 · 0 评论 -
普林斯顿公开课:算法第0章,课程介绍
课程介绍这门课程核心内容是算法和数据结构。具体的算法和数据结构如下:数据类型:堆栈、队列、背包、并查集、优先队列。排序:快排、并排、堆排、基数排序查找:BST、红黑BST、哈希表图:BFS、DFS、Prim、Kruskai、Dijkstra字符串:KMP、正则、TST、哈夫曼、LZW高级:B树、后缀数组、最原创 2014-05-30 19:15:11 · 2888 阅读 · 1 评论 -
算法5-5:线段交叉问题
问题给定一系列线段,每条线段可以是水平或者竖直。求相交的线段解决算法的基本思想是先将线段以x坐标进行排序。做一条扫描线,从左往右扫描,也就是下图中的红线。当进入一条水平的线时,记录该线段的y坐标。当走出水平线时,从二叉查找树中删除该线段的y坐标。原创 2014-06-11 19:08:33 · 2159 阅读 · 0 评论 -
算法4-6:关联数组的基本实现
本节主要介绍键值对表的基本实现方法。链表法一种方法就是用链表进行实现。这种方法的基本思想就是用链表储存键值对。当需要寻找一个值时,扫描整个链表,如果有匹配的键,就返回对应的值。当需要插入一个值时,扫描整个链表,如果能够找到匹配的键,就覆盖对应的值,如果没有找到,就在链表的头部增加一个新的键值对。这种算法查找操作和插入操作的复杂度均为N,性能很原创 2014-06-10 19:43:13 · 1226 阅读 · 0 评论 -
算法5-6:Kd树
问题给定一系列的点,和一个矩形。求矩形中包含的点的数量。解答这个问题可以通过建立矩阵来进行求解。首先将一个空间分割成矩阵,将点放置在对应的格子中,再计算矩形覆盖的格子,再判断格子中的点是否包含在矩形中这种方法的问题是,可能这些点全都集中在一个格子中。这种情况下算法的效率比较低。原创 2014-06-13 20:00:06 · 1189 阅读 · 0 评论 -
算法5-7:区间搜索
区间搜索问题就是给定一系列区间,和一个待测区间,求与待测区间相交的区间。为了解决这个问题,需要专门编写一个类,这个类的接口如下:public interface IntervalST, Value> { void put(Key lo, Key hi, Value value); Value get(Key lo, Key hi) voi原创 2014-06-13 20:01:08 · 1634 阅读 · 0 评论 -
算法5-8:矩形相交
在70年代,计算机已经发展了一段时间,芯片的规模也越来越复杂。因此人们不得不发明一些芯片设计的软件,在软件中完成芯片的设计、调试工作。当时,模拟运行的时候根据电路的设计,模拟的过程中需要不断地判断矩阵是否相交。那时候还没有很好的算法,人们只能通过暴力手段逐个判断矩阵是否相交。在今天看来,这种算法的复杂度是N^2。根据摩尔定律,计算机CPU每隔18个月,晶原创 2014-06-13 20:03:08 · 1240 阅读 · 0 评论 -
算法6-1:哈希函数
在上章节中已经介绍了通过红黑树实现键值对数组的查询操作,复杂度是logN。有没有性能更好的算法呢?答案是有。基本想法就是计算关键字的哈希值,再通过哈希值直接获取对应的键值。这种方法的需要解决的问题是:如何计算哈希值如何解决哈系冲突哈希函数目标根据对象中的成员变量的值,按照一定的规则计算出一个原创 2014-06-13 20:05:07 · 1232 阅读 · 0 评论 -
算法6-2:解决哈系冲突之独立链表
独立链表是解决哈希冲突的一种办法。它的基本思想就是将哈希值相互冲突的几个对象放到一个链表中。代码public class HashST { private static class Node { Object key; // 由于无法创建泛型数组,只能将对象设置为Object类 Object value; Node n原创 2014-06-13 20:05:58 · 1174 阅读 · 0 评论 -
普林斯顿公开课 算法1-1:算法分析
为什么要分析算法分析算法可以预测算法的性能,比较算法之间的优劣,保证算法的正确性,理解算法的理论基础。成功算法的例子离散傅立叶变换,如果使用暴力方法,那么算法的复杂度是是N^2,如果使用FFT快速傅立叶变换可以实现O(N logN)复杂度N-body模拟:使用Barnes-hut算法可以将复杂度降低到N logN原创 2014-05-30 19:52:31 · 3344 阅读 · 0 评论 -
普林斯顿公开课 算法2-1:排序概述
目标对所有类型的数据进行排序。问题排序函数如何知道比较的是哪种类型的数据呢?回调函数这时候就需要引入回调函数的概念了。回调函数就是将可执行的代码作为参数进行传递。实现回调的方法在Java中可以通过接口来实现,在C语言中可以通过函数指针来实现,C++中可以通过class-type functor,也就是重载操作符oper原创 2014-06-02 17:46:40 · 1634 阅读 · 0 评论 -
算法6-3:解决哈希冲突之线性探针
线性探针是另外一种解决哈希冲突的办法。这种办法的基本思想就是当遇到哈希冲突时,寻找下一个空位,直到找到空位为止。示例先插入一个值S,如下图。插入其他的一些值,这些值的哈系没有冲突,得到下图的结果。再插入一个值H,由于H与A的哈系冲突,因此需要寻找一个空的位置。找到了空位原创 2014-06-16 19:00:14 · 1896 阅读 · 0 评论 -
算法7-8:有向图接口
有向图和无向图在编程中的表示方法是差不多的,本问介绍邻接表表示方法。有向图对象的代码轮廓如下:public class Digraph { public Digraph(int v) { } // 创建v到w的边 public void addEdge(int v, int w) { } // 获取v能直接到达原创 2014-06-18 18:57:33 · 989 阅读 · 0 评论 -
算法7-9:有向图搜索算法
深度优先算法问题给定一个有向图,判断其顶点能否到达另外一个顶点。解决办法使用深度优先算法,和无向图中的是一样的。代码import java.util.Stack; /** * Created by caipeichao on 14-6-11. */ public class Digrap原创 2014-06-18 18:58:56 · 2768 阅读 · 0 评论 -
算法7-10:拓扑排序
在一个软件工程项目中,有些任务需要在另外一个任务完成之后才能完成,这种任务在软件工程中是非常常见的。下图就展示了一个软件项目的依赖情况。这张图非常明显,就是一张有向图。那么,现在问题就来了,如何输出任务的完成顺序呢?这个问题有一个前提条件,就是有向图中不能出现回路。算法的基本思想就是在每次dfs返回时将顶点加入到返回结原创 2014-06-18 19:00:16 · 1264 阅读 · 0 评论 -
算法8-2:最小生成树贪婪算法
为了简化问题,我们需要作出一些假设。假设图中每条边的权重都是不一样的,假设整个图是连通的。这样假设的目的就是让最小生成树的计算结果是唯一的。图的切割介绍算法之前,需要先了解图的切割。图的切割就是将顶点分割成两部分,切到的边称之为交叉边。下图红色的先就是交叉边。在最小生成树中,无论如何切割,最小生成树总是从交叉边中选择最小的原创 2014-06-19 20:25:47 · 1460 阅读 · 0 评论 -
算法8-1:最小生成树简介
最小生成树是图论中的一个概念。首先介绍一下什么是生成树。生成树就是将一个图中所有的顶点全部连接在一起,并且保证图中没有出现回路。下图不是生成树,因为没有连接所有的顶点。下图不是生成树,因为图中有回路。像下图这样的才是生成树。生成树的概念介绍完了。那么最原创 2014-06-19 20:23:57 · 1007 阅读 · 0 评论 -
算法8-4:Kruskal算法
Kruskal算法用于计算一个图的最小生成树。这个算法的步骤如下:按照边的权重从小到达进行排序依次将每条边增加到最小生成树中,除非这条边会造成回路实现思路第一个步骤需要对边进行排序,排序方法在之前的章节中已经介绍了很多,可以使用优先级队列进行实现,也可以使用归并排序进行实现,这里采用归并排序。第二个步骤需要判断是否会造原创 2014-06-20 19:46:32 · 1079 阅读 · 0 评论 -
算法8-5:Prim算法
Prim算法用于计算最小生成树。Prim算法分为两种,一种是懒汉式,一种是饿汉式。懒汉式Prim懒汉式Prim算法步骤如下:首先将顶点0加入到MST中从MST与未访问顶点之间边中选出最短的边,在满足MST的前提下,将这条边加入到MST代码import java.util.LinkedList;import jav原创 2014-06-20 19:47:27 · 1384 阅读 · 0 评论 -
算法8-3:权重图接口
在正式编写最小生成树的算法之前,还需要做一些准备工作。具体的工作就是建立一些基础对象。边首先需要建立边的对象。现在的边要增加权重信息,一条边需要记录两个端点以及这条边的权重,因此边类的轮廓如下:public class Edge implements Comparable { public Edge(int v, int w, double we原创 2014-06-20 19:45:13 · 1628 阅读 · 0 评论 -
算法7-7:有向图简介
有向图就是在无向图的基础上进行改进,使得每条边都有方向。应用有些公路只能单个方向行驶。如果要对地图建立数学模型,那用有向图就比较方便了。下图是政府博客之间的引用关系,也是有向图。下图是银行之间的贷款联系,用的也是有向图。电路中的二极原创 2014-06-18 18:55:57 · 1590 阅读 · 0 评论 -
算法7-11:强连接部件
首先介绍什么是强连接。顶点之间的强连接就是如果v能到达w,那么w也能到达v。顶点之间的强连接就表示顶点之间可以双向到达,也就是说两个顶点在一个回路上。介绍了强连接,那什么是强连接部件呢?强连接部件就是能够相互到达的所有顶点的集合。一个图中可能会有多个强连接。强连接在离散数学中属于等价关系,也就是说它具有反射性,相反性,传递性。应用原创 2014-06-18 19:01:11 · 2211 阅读 · 0 评论 -
算法6-6:哈希表应用之字典应用
该应用的目标是实现CSV文件的查询操作。运行举例java QueryCSV dns.csv 0 1baidu.com123.125.114.144zjgsu.edu.cn202.96.99.58代码代码中使用了普林斯顿大学的Java标准库,请戳这里下载:http://introcs.cs.princeton.edu/java/stdlib/原创 2014-06-16 19:05:18 · 1143 阅读 · 0 评论 -
算法6-4:哈希表现状
战争故事很久很久以前,曾经发生过很多关于哈希函数的战争故事。那些战争的基本原理就是通过精心构造造成大量的哈希冲突从而占用大量的CPU资源。被攻击的软件例有以下例子:带有漏洞的服务器:攻击者精心构造哈系冲突,只需要56K的网速就能让服务器死机,从而达到DOS攻击的目的。Perl 5.8.0:攻击者精心构造哈系冲突插入到关原创 2014-06-16 19:02:02 · 1055 阅读 · 0 评论 -
算法6-5:哈希表应用之集合
可以通过哈希表实现高效的集合操作。接口一个集合对象可以包含了以下接口:public interface Set> { public void add(Key key); public boolean contains(Key key); public void remove(Key key); public int siz原创 2014-06-16 19:03:41 · 1000 阅读 · 0 评论 -
算法7-2:图论接口
本节介绍如何在程序中表示一张图。顶点在程序中,顶点用整数表示就可以了。因为整数可以作为数组的下标,也可以作为哈希表的键。所以用整数是最方便的。当然,在一张图中可能会出现一些异常情况,比如自己连接自己,两个顶点之间存在多个边。这些异常情况也是要考虑的。接口为了表示一张图,就要创建专原创 2014-06-17 20:00:59 · 1125 阅读 · 0 评论 -
算法7-4:宽度优先搜索
宽度优先搜索的基本思想就是先将源点添加到一个队列中, 每次从队列中取出一个顶点,将该顶点的邻居顶点中没有拜访过的顶点都添加到队列中,最后直到队列消耗完毕为止。应用宽度优先搜索可以解决最短路径问题。而最短路径算法在互联网中应用非常广泛,尤其是路由这块。因为路由追求的是高效,所以每个路由路径都是通过最短路径计算出来的。如果没有最短路径算法,我们可能就享受不到这么快的原创 2014-06-17 20:02:51 · 1267 阅读 · 0 评论 -
算法7-5:连接部件
同学们一定用过Windows中的画图吧。那么画图中的油漆桶功能是如何实现的呢?这个问题可以通过DFS深度优先搜索解决。目标我们要实现的目标是在常数的时间内判断某两个节点是否连接。前面章节中介绍了并查集算法,并查集确实可以解决这个问题。我们今天来介绍另外一种办法,那就是DFS深搜。原创 2014-06-17 20:04:49 · 1077 阅读 · 0 评论 -
算法7-6:图论中的难题
二部图难度:★★二分图是图论中的一种特殊模型,指顶点可以分成两个不相交的集使得在同一个集内的顶点不相邻(没有共同边)的图。下图是一个二分图的例子,红点之间不会相邻,白点之间不会相邻。判断图中是否存在环难度:★★通过深搜就可以解决了。欧拉环原创 2014-06-17 20:05:51 · 1428 阅读 · 0 评论 -
算法7-3:深度优先搜索
深度优先搜索最初是因为迷宫游戏而诞生的。在一个迷宫中,有一个入口和一个出口,其中只有一条路径能从入口到达出口。在走迷宫的时候,每次将走过的地方进行标记,遇到死胡同的时候可以沿着进来的路线后退,找到新的没走过的拐角再尝试新的路线。这种方法的效率很高,因为每个地方只需要走过一次即可。其实,这就是深度优先搜索。深度优先搜索的目标就是系统化地遍历整个图,让算法的效率更高。原创 2014-06-17 20:02:05 · 1039 阅读 · 0 评论 -
算法5-4:1d范围查找
有一个整数集合,求所有介于x到y之间的所有整数实现方法非顺序数组:复杂度是N,比较慢顺序数组:查找操作的复杂度是lgN,插入操作的复杂度是N二叉查找树:复杂度是logN,比较快代码下面这段代码用于统计lo到hi之间的整数个数public int count(Key lo, Key hi) { i原创 2014-06-11 19:07:24 · 1153 阅读 · 1 评论