0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

算法大神Tarjan

算法与数据结构 来源:算法与数据结构 作者:算法与数据结构 2021-01-04 14:23 次阅读

有同学在学习图论算法的时候,发现这里有个 Tarjan 算法,那里有个 Tarjan 算法,而似乎 Tarjan 算法解决的问题并不一样,于是非常迷惑:Tarjan 算法到底是指什么?

这是一个很好的问题。Tarjan 是计算机领域的大牛,发明了很多现在大家耳熟能详的算法或者数据结构,所以有同学会觉得冠他名字的算法有些多。

但如果我们仔细梳理一下,其实并不复杂。

在这篇文章中,我会带领大家梳理一下 Tarjan 发明的算法都有哪些,整体脉络是怎样的。

注意:在这篇文章中,我不会具体讲解某个算法的原理。但是,我会给出很多具体的关键字,并且标红。如果大家对某个算法想深入了解,可以以此为引,在互联网上搜索学习。

我相信,互联网上关于某个具体算法的资料是非常多的,反而是这样按照某个脉络做总结的文章很少。

首先,Tarjan 是一名美国的计算机科学家和数学家,全名 Robert Endre Tarjan。

先来一个 Tarjan 大神的名言镇楼:

一般提起 Tarjan 算法,通常是指 Tarjan 发明的求解有向图的强联通分量算法,全称是Tarjan’s Strongly Connected Components Algorithm.

为什么这么叫?因为求解有向图的强联通分量还有一个著名算法:Kosaraju 算法。Kosaraju 算法也是以他的发明者的名字命名的。

我在算法比赛中,或者需要求解 SCC(强连通分量的缩写:Strongly Connected Components) 问题的时候,喜欢写 Kosaraju 算法。因为 Kosaraju 算法的实现非常简单,复杂度和 Tarjan 算法是一样的,都是 O(V + E) 的。

但实际上,Kosaraju 算法需要遍历两次图,而 Tarjan 算法只需要遍历一次图。所以,Tarjan 算法的性能更高,一般可以高 30% - 40% 左右。

而 Tarjan 算法之所以有名,关键在于使用 Tarjan 算法的思想,不仅仅可以求解 SCC 问题,还可以求无向图中的桥或者割点。

这就是为什么,很多同学看到 Tarjan 算法,做的事情不一样,但都叫 Tarjan 算法的原因。我们可以把 Tarjan 算法理解成是一种思想,基于这种思想,可以求解桥,割点,和 SCC 问题。

所谓的 Tarjan 算法思想,就是在遍历整个图的过程中,对每一个遍历的节点记录一个时间戳,通常被称为是 DFN;同时,记录通过这个节点,不经过父亲节点,最早能回到的时间戳,通常被称为是 LOW。通过这些信息,就能判断一个图的桥,割点,和强连通分量。

2ae9bf46-4423-11eb-8b86-12bb97331649.png

然而,Tarjan 的贡献远不止于此。以Tarjan命名的另外一个非常著名的算法,叫Tarjan‘s Off-line Least Common Ancestors Algorithm。

这个算法本质是借助并查集,求解 LCA(最近公共祖先的缩写:Least Common Ancestors)问题。

实际上,离线的 LCA 问题,是计算机科学领域非常著名的问题,深究下去,和Binary Lifting,RMQ等非常著名的算法思想都有联系。

2b0ed164-4423-11eb-8b86-12bb97331649.png

说到并查集,Tarjan 也和这种数据结构有不解之缘。并查集虽然不是 Tarjan 发明的,但是并查集的复杂度是 Tarjan 首先分析清楚的:也就是Ackerman 函数的反函数。

如果对此感兴趣的同学,可以翻看《算法导论》,《算法导论》对这部分内容介绍得很清楚。

实际上,这也是《算法导论》这本教材的意义:稍微深入一些的算法分析问题,一般的算法教材都不会涉及。而《算法导论》所覆盖的深度和广度,比大多数教材都高太多。

当然,这也是《算法导论》不适合入门的原因。

说到数据结构,Tarjan 确实发明过数据结构。最有名的两个,一个是斐波那契堆,一个是Splay 树。

Splay 树虽然不保证一定平衡,但各个操作的均摊复杂度是 O(logn) 级别的。

Splay 树最大的优势是实现简单,比红黑树简单不知道多少倍。所以,如果我们需要调用更加底层的树操作,需要自己实现一个自平衡的二分搜索树时,通常 Splay 树是首选。

也正因为如此,很多搞竞赛的同学,都是能手写 Splay 树的。

Tarjan 还是非常著名的算法:BFPRT的作者之一。其实 BFPRT 这个算法的名字,是其五个作者首字母的缩写。其中的 T,就是 Tarjan。

BFPRT 这个名字听起来非常拗口,同时也难记,但是它的另一个名字就很简单直接了,就是Median of Medians。

这个算法整体并不难理解,是快排思想的一种更稳定的优化,每次近乎可以保证选取所处理的数组的中位数作为标定点(pivot),使得快速排序的最差时间复杂度真真正正达到了 O(nlogn)。

值得一提的是,BFPRT 算法的这五位作者,都是计算机科学领域的大牛。他们分别是:

B是 Blum,全名 Manuel Blum,他因为复杂度理论方面的贡献,以及密码学的应用,获得了 1995 年的图灵奖;

F是 Floyd,全名 Robert W. Floyd,相信大家都很熟悉。大家在算法课本上一定会学到的所有点对的最短路径算法,就是他和 Warshall 一起提出的,即Floyd–Warshall 算法。同时,Floyed 还提出了非常著名的Floyed 环检测算法。他获得了 1978 年的图灵奖;

P是 Pratt,全名 Vaughan Pratt,是斯坦福的教授;

R是 Rivest,全名 Ron Rivest。他是 MIT 的教授,专攻密码学。我们现在所经常使用的MD5 算法,他就是作者之一;

最后的T,就是这篇文章的主角:Tarjan,全名 Robert Endre Tarjan。

在图论领域,Tarjan 还改进了一个非常著名的算法:最小树形图。最小树形图这个名字听起来很复杂,但其实这个概念很简单:就是有向图的最小生成树。

解决最小树形图问题,有一个非常朴素的算法,叫朱刘算法。听这个名字大家也知道,这是两位华人科学家首先提出来的算法,在论文记载中,分别是 Y.J. Chu 和 T.H. Liu 在 1965 年提出来的。朱刘算法的时间复杂度是 O(VE) 的。

后来,Tarjan 改进了这个算法,可以使用 O(ElogV) 的时间做预处理,之后使用 O(V) 的时间,求解图中以任意顶点为根的最小树形图

Tarjan 还发明了一种平面图的检测算法,首次在线性时间解决了平面图检测问题(Planarity-Testing)。因为平面图检测离大多数同学的工作比较远,所以可能很少有同学了解这个算法。

Tarjan 的平面图检测算法还有一个合作者:John Hopcroft。他们二人因为这个算法,以及在算法和数据结构等基础领域对计算机科学的贡献,获得了 1986 年的图灵奖。

Tarjan 的硕士和博士是在斯坦福大学读的。他的导师有两个。一个就是大名鼎鼎的 Floyd,上文介绍 BFPRT 算法的时候介绍了。在这里给一个年轻的时候,Floyd 风流倜傥的帅照:

Tarjan 的另一名导师,则是计算机科学领域的神级人物:Donald Knuth。他可以说是计算复杂领域的创始人。

Donald Knuth 的经历和贡献,可以写一本书了。有时间,我会再写一篇文章介绍他。现在,很多人了解他,都是因为他的神作:TAOCP,即The Art of Computer Programming,被中文翻译成《计算机程序设计艺术》。这套书被评为至今计算机科学史上最重要的神作,但其实还没有写完。

不过 Donald Knuth 对计算机科学领域的贡献,远不止一套书这么简单。要聊 Donald Knuth 的话,能聊的就太多。这篇文章我们收一收,说回 Tarjan。

Tarjan 现在还在世,今年已经 72 岁了。根据维基百科,现在 Tarjan 在普林斯顿任教。

实际上,在计算机科学领域,很多在教科书中出现的人物,都还在世;很多教科书级别的算法,概念,理论,其实距离提出,也不过是几十年的时间。

这足以可见:计算机是多么年轻的一个学科。

也正是因为这个原因,在计算机科学领域中,还有大量的没有被完全解决的问题。

计算机科学领域其实还大有可为。

责任编辑:xj

原文标题:Tarjan 这个算法大神

文章出处:【微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算法
    +关注

    关注

    23

    文章

    4456

    浏览量

    90849
  • 计算机
    +关注

    关注

    19

    文章

    6654

    浏览量

    84762

原文标题:Tarjan 这个算法大神

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    AURIX TC397是否可以搭配Google TensorFlow的演算法去运算?

    请问各位大神,AURIX TC397 是否可以搭配 Google TensorFlow 的演算法 去运算??
    发表于 02-18 06:05

    大神医齐现身,竟为医院数据中心而来?

    大神医齐聚,为了给医院数据中心“把把脉”
    的头像 发表于 12-14 23:02 188次阅读
    三<b class='flag-5'>大神</b>医齐现身,竟为医院数据中心而来?

    常用的校验算法有哪些?

    常用的校验算法有哪些,是不是和通信规约有关。比如MODBUS一般都用CRC16(不确定是不是叫这个)。这些校验算法是之前积累下来的吗。自己也可以定义一个校验算法吧,只要发送端和接收端用同一个
    发表于 11-03 06:50

    STM32的PWM波形输出配置的大神总结

    STM32的PWM波形输出配置的大神总结
    的头像 发表于 10-24 16:00 2364次阅读
    STM32的PWM波形输出配置的<b class='flag-5'>大神</b>总结

    大神教你30条PCB设计时提升降噪与抗电磁干扰能力的技巧,必看!

    大神教你30条PCB设计时提升降噪与抗电磁干扰能力的技巧,必看!
    的头像 发表于 10-17 15:16 365次阅读

    卡尔曼滤波算法对比其他的滤波算法有什么优点?

    卡尔曼滤波算法对比其他的滤波算法有什么优点
    发表于 10-11 06:42

    stc89c52怎么加入傅里叶算法来测量体温脉搏?

    毕业设计题目是基于单片机的体温脉搏测量系统,请教大神怎样加入傅里叶算法来测量体温脉搏,并且得到结果后又该用什么方法后者算法来分析得到的结果
    发表于 10-08 06:39

    C语言经典算法大全

    C语言经典算法,详细解析算法过程及算法思想,给读者具有启发意义,教程包含C语言大部分常用算法,仅供学习,禁止商业传播
    发表于 10-07 08:16

    大神手工自制CPU的过程

    为了深入理解这个问题,大神耗时整整半年,“逐点”焊接,自制了一个CPU,杰作如下图所示。
    的头像 发表于 09-27 09:41 626次阅读
    <b class='flag-5'>大神</b>手工自制CPU的过程

    c语言算法大全

    1 适合算法竞赛或兴趣了解 2 本套算法均是已实现算法 3 算法均有本人查阅和自己写 4 未经允许不得做为商业用途
    发表于 09-27 06:51

    AI算法有哪些?

    AI算法有哪些? 随着人工智能技术的不断发展和应用,越来越多的AI算法被发明和应用于各个领域。本文将介绍一些常见难度较低但易于理解的AI算法,以及一些当前比较流行的AI算法。 一、基本
    的头像 发表于 08-24 15:40 2031次阅读

    机器学习有哪些算法?机器学习分类算法有哪些?机器学习预判有哪些算法

    机器学习有哪些算法?机器学习分类算法有哪些?机器学习预判有哪些算法? 机器学习是一种人工智能技术,通过对数据的分析和学习,为计算机提供智能决策。机器学习算法是实现机器学习的基础。常见的
    的头像 发表于 08-17 16:30 1432次阅读

    机器学习算法入门 机器学习算法介绍 机器学习算法对比

    机器学习算法入门 机器学习算法介绍 机器学习算法对比 机器学习算法入门、介绍和对比 随着机器学习的普及,越来越多的人想要了解和学习机器学习算法
    的头像 发表于 08-17 16:27 644次阅读

    机器学习算法汇总 机器学习算法分类 机器学习算法模型

    机器学习算法汇总 机器学习算法分类 机器学习算法模型 机器学习是人工智能的分支之一,它通过分析和识别数据模式,学习从中提取规律,并用于未来的决策和预测。在机器学习中,算法是最基本的组成
    的头像 发表于 08-17 16:11 736次阅读

    Dijkstra算法和A*算法

    在本文中,我们将主要介绍Dijkstra算法和A*算法,从成本计算的角度出发,并逐步展开讨论。 我们将从广度优先搜索开始,然后引入Dijkstra算法,与贪心算法进行比较,最终得出A*
    的头像 发表于 07-07 10:56 646次阅读
    Dijkstra<b class='flag-5'>算法</b>和A*<b class='flag-5'>算法</b>