数据结构与算法分析
文章平均质量分 95
数据结构与算法二者相辅相成、密不可分;算法的具体实现常需要依赖于特定的数据结构,数据结构的一些操作本身又是算法。本专栏详尽地介绍各种高级数据结构(包含但不限于KD-Tree、R-Tree等)并讲解算法设计思想与算法分析(例如各种复杂度分析方法、计算理论等)方法与技巧
白马负金羁
数据挖掘 | 统计分析 | 图像处理 | 程序设计
展开
-
高级数据结构之Fenwick Tree(Binary Indexed Tree)
Fenwick Tree也叫做树状数组,或者二叉索引树(BIT,Binary Indexed Tree),由新西兰奥克兰大学的Peter Fenwick博士于1994年提出。Fenwick Tree用数组来表示一棵树(这样空间上更节约),所以它的结点中没有指向左右孩子的指针这样的设计。它可以用于对区间和(range sum)进行快速查询,其元素修改和区间查询的复杂度都是O(log n)原创 2021-06-07 13:54:45 · 613 阅读 · 0 评论 -
高级数据结构之线段树(Segment Tree)
线段树(Segment Tree)也是一种树形的数据结构,只不过树中结点存储的值是一个区间或一个线段。 常用于区间内数值的查询操作,比如一个区间内的最大值(max),最小值(min),以及加和(sum)等等。该结构由美国计算机科学家Jon Bentley于1977年提出原创 2021-06-06 12:34:33 · 518 阅读 · 0 评论 -
高级数据结构之B树(B-tree)
一、B树(B-tree)的定义B树是二叉树的一种推广,它在以硬盘为主的多级存储结构中常常被用来执行高效搜索。下图是一棵B树的简单示例,其中存储的是英语中的辅音字母。如果B树的一个内部结点x包含有x.n个关键字,那么它就会有x.n+1个孩子。结点x中的关键字是有序排列的,而且这些有序的关键字也把以x为根的子树中所包含关键字分隔成x.n+1个子域,每个子域对应一棵子树。当在一棵B树中查找一个关键字...原创 2019-05-09 11:53:51 · 4903 阅读 · 3 评论 -
高级数据结构之R树(R-tree)
R树(R-tree)是一种将B树扩展到多维情况下得到的数据结构,它最初由Antonin Guttman于1984年提出。B树的结点中会存储一个键的集合,这些键把线分成片段,沿着那条线的点仅属于一个片段。因此,B树使得我们可以很容易地找到点。如果把沿线各处的点表示成B树结点,我们就能够确定点所属唯一子结点,在那里可以找到该点。Antonin Guttman在他提出R树的经典论文中给出的R树例子...原创 2020-01-22 09:42:33 · 11744 阅读 · 2 评论 -
高级数据结构之K-D-TREE
k-d-tree(即k-dimensional tree)是一棵形如二叉树的一种非常重要的空间划分数据结构,尤其在多维数据访问中有重要应用。特别是机器学习中的kNN(k近邻)最常用到的搜索算法就是以k-d-tree为依托来执行的。k-d-tree是由Jon Bentley 于1975年提出的,Jon Bentley 也是畅销书《编程珠玑》的作者原创 2016-10-26 21:42:49 · 5966 阅读 · 5 评论 -
Barnes-Hut算法(quad-tree的一个应用)
Barnes-Hut算法是一种用于实现N体问题(n-body)模拟的近似算法,该算法由Josh Barnes 和 Piet Hut在1986年提出,其中还运用了quad-tree(或者 octree)这个数据结构。N体问题是指找出已知初始位置、速度和质量的多个物体在经典力学情况下的后续运动。庞加莱(Henri Poincaré)在研究N体问题时,发现了混沌现象原创 2016-11-05 12:00:33 · 11339 阅读 · 2 评论 -
主定理(Master theorem)与Akra–Bazzi定理
主定理是算法分析中的一个重要结论,它主要用于求解基于分治思想设计的递归算法的渐进复杂度。经典教材《算法导论》中也介绍过这个结论。尽管主定理应用起来十分方便,但并非所有的递归关系都可以用它来求得最终的渐进表示的复杂度。一个更加泛化的结论是由数学家Mohamad Akra 和 Louay Bazzi在1998年给出的后来以他们名字命名的定理——Akra-Bazzi定理原创 2020-08-30 03:02:37 · 10198 阅读 · 15 评论 -
堆的构建算法具有线性时间复杂度O(n):解释与证明
堆是一种非常有用的数据结构类型,它可以用作执行优先级队列的存储结构,也可以用来实现堆排序。BUILD-HEAP算法(即建堆算法)的功能是从无序的输入数组中构建一个堆(最大堆或者最小堆),它是具有线性时间O(n)复杂度的算法。本文将讨论如何解释及证明这个结论原创 2015-11-14 12:49:19 · 6269 阅读 · 1 评论 -
分治策略:以字符串(或线性表)切分成连续子序列为例讨论
分而治之是算法设计中一个非常重要的思想,经典的汉诺塔问题就是利用分治策略进行求解的代表性问题。下面将从一个具体问题出发,讨论分治策略的使用,并给出在Python中的实现...原创 2018-12-24 11:43:29 · 2353 阅读 · 46 评论 -
树(或有向无环图)中根结点到所有叶子的路径
假设现在有一棵树,注意这里的树不一定是二叉树(也即可以是多叉树),我们希望枚举出从根结点到每一个叶子结点的路径,这个算法该如何实现?本文中的例子主要采用Python来实现。为了方便构建一棵树(还有后面的有向图),这里直接使用Python中NetworkX包,NetworkX是一个用Python语言开发的图论与复杂网络建模工具原创 2020-05-29 06:55:27 · 7043 阅读 · 0 评论 -
如何学好算法和数据结构之我见
数据结构与算法课程是大学计算机专业的重要基础课程。考研中,数据结构也几乎是专业课之必考。在实际工作中,数据结构依然很有用。至少很多公司面试笔试也会考的。如果你数据结构知识为零,那基本上是无法从事“更有质量”的开发工作的。尽管数据结构非常重要,但这门课由于逻辑性要求较强,非常抽象,很多学生面对它都显得力不从心原创 2010-10-26 21:41:00 · 7500 阅读 · 47 评论 -
算法与数据结构学习资源大搜罗——良心推荐
数据结构与算法设计是CS相关专业的必修课,也是IT公司笔试面试的重点。网上这方面的资料多如牛毛,我列出了一些我认为非常值得推荐的资源,供有需求的读者研习之用。首先是一些网络资源,然后是一些书籍点评和推荐。不断更新中,但大浪淘沙,我只保留最值得推荐的原创 2016-01-17 12:30:35 · 14067 阅读 · 14 评论 -
模拟退火算法系列之(一):通俗理解
为什么我的眼里常含泪水?因为我有一个算法不会。为了节约点眼泪,今天我们就来介绍著名的模拟退火算法,它是一种基于蒙特卡洛思想设计的近似求解最优化问题的方法。〇、一点历史——如果你不感兴趣,可以跳过美国物理学家 N.Metropolis 和同仁在1953年发表研究复杂系统、计算其中能量分布的文章,他们使用蒙特卡罗模拟法计算多分子系统中分子的能量分布。这相当于是本文所探讨之问题的开始...原创 2009-09-06 23:39:00 · 11537 阅读 · 24 评论 -
模拟退火算法系列之(二):一个实例
模拟退火算(Simulated Annealing)法是一种基于蒙特卡洛思想设计的近似求解最优化问题的方法。本文通过一个实例来编程演示模拟退火的执行。特别地,我们这里所采用的实例是著名的“旅行商问题”(TSP,Traveling Salesman Problem),它是哈密尔顿回路的一个实例原创 2016-09-18 13:37:16 · 30579 阅读 · 5 评论 -
道格拉斯-普克算法(Douglas–Peucker algorithm)
道格拉斯-普克算法(Douglas–Peucker algorithm),亦称为拉默-道格拉斯-普克算法(Ramer–Douglas–Peucker algorithm),是在GIS中非常常用的一种基础算法。对于一条有N个点来描述的曲线,道格拉斯-普克算法可以在尽量保持曲线形状的条件下用更少的点来描述原曲线原创 2009-09-18 01:03:00 · 9696 阅读 · 14 评论 -
Flajolet-Martin算法
今天我们来介绍著名的Flajolet-Martin算法法,它被用来估计集合中(也就是不重复的)元素的个数。尽管这是一种在上世纪80年代被提出的算法,但是今天这个时代再来探讨它似乎更有意义,因为它是一种真正的“大数据”算法原创 2009-08-17 17:53:00 · 5702 阅读 · 13 评论 -
RSA加密算法
RSA加密算法是一种非对称加密算法,它在公开密钥加密和电子商务中具有广泛应用。非对称加密体制中,加密和解密秘钥是不同的(或者已知公钥很难推得私钥)。公钥被用来对数据进行加密,私钥被用来对数据进行解密,公钥可以在信道上进行传输,而私钥只有解密方才知道且无需与他人分享原创 2009-08-21 16:38:00 · 2764 阅读 · 15 评论 -
A*寻路算法的最简单通俗讲解
为什么我的眼里常含泪水?因为我有一个算法不会。为了节约点眼泪,今天我们就来介绍著名的A*寻路算法(或简称A*算法)。Peter Hart, Nils Nilsson 和 Bertram Raphael 在1968年首次提出了著名的A*算法。A*算法其实是Dijkstra最短路径算法的一种扩展。不一样的是,在A*算法中我们需要使用Heuristics 来导引搜索过程,以期达到更好的表现。...原创 2016-01-23 13:54:36 · 18581 阅读 · 6 评论 -
分散层叠(Fractional Cascading)
Fractional Cascading是用来进行多列查询(或交互查询)的一种高效算法,同时它也是计算几何中用来帮助Range Tree提升搜索效率的一种重要方法。本文就将对这个思想来做一番详细的解读,以帮助你理解到底什么是Fractional Cascading原创 2016-10-28 22:55:53 · 6744 阅读 · 0 评论 -
威尔逊定理
十八世纪中叶,一位英国法官约翰·威尔逊爵士,发现了数论中一种极为罕见的关系,这就是数论中的威尔逊定理。威尔逊定理给出了判定一个自然数是否为素数的充分必要条件原创 2009-07-07 11:25:00 · 6872 阅读 · 19 评论 -
中国剩余定理
中国古代数学著作《孙子算经》中首先提到了“物不知其数”问题,也就是所谓的求解一次同余式组的问题。后来宋代数学家秦九昭其所著的《数书九章》中对“物不知数”问题做出了完整系统的解答。这也是数论中一个重要定理,又称中国剩余定理原创 2009-08-10 17:33:00 · 3746 阅读 · 16 评论 -
数组排序同时返回元素在原数组中的位置
对数组中的元素进行排序是非常基础的问题,从现有的众多排序算法中任选一种即可实现。但是如果要求排序后同时返回新的(有序)数组中每个元素在旧的(未排序)数组中之原始位置,问题可能就变得有些棘手了原创 2015-10-27 19:23:07 · 10675 阅读 · 0 评论 -
算法分析之大O、大Ω、大Θ和小o表示法
算法分析中常常使用大O表示法、大Ω表示法、大Θ表示法和小o表示法来对算法复杂度进行分析。本文就将从多个角度来讨论它们的具体定义并给出一些例子,其中大O表示法、大Ω表示法、大Θ表示法可以视为一种组合,而大O表示法和小o表示法又被视为另外一种组合,搞清楚同一组内各种记号系统的关系非常重要原创 2010-11-23 11:51:00 · 10465 阅读 · 12 评论 -
从哈密尔顿路径谈NP问题
1859年,爱尔兰数学家哈密尔顿(Hamilton)提出下列周游世界的游戏:在正十二面体的二十个顶点上依次标记伦敦、巴黎、莫斯科等世界著名大城市,正十二面体的棱表示连接这些城市的路线。试问能否在图中做一次旅行,从顶点到顶点,沿着边行走,经过每个城市恰好一次之后再回到出发点。这就是著名的哈密尔顿问题。哈密尔顿问题是一个著名的NP问题。原创 2015-11-06 21:01:35 · 29169 阅读 · 3 评论 -
计算理论中的莱斯定理(Rice's Theorem)——证明与应用
计算理论中,可判定性时研究算法局限的一个重要方面,由这方面的理论我们知道,算法不是万能的。确实存在一些算法上不可解的问题。本文给出一个在探讨不可判定性时非常有用的结论——莱斯定理(Rice's Theorem),或称赖斯定理。原创 2015-12-04 21:23:50 · 20775 阅读 · 5 评论 -
各种求圆周率π的算法(蒙特卡洛法的Java实现)
算法就是有穷规则构成的用于解决某一类问题的运算序列或执行步骤。要解决一个问题可能会有不同的方法,针对求圆周率π的近似值这个问题你能想到多少种算法呢?本文讨论三种计算方法,并在Java中实现其中基于蒙特卡洛模拟的方法原创 2017-03-02 12:52:45 · 16313 阅读 · 4 评论