高产的计算机科学家——Tarjan
来源:互联网 发布:少女前线数据配置失败 编辑:程序博客网 时间:2024/05/17 05:12
提到 Robert Tarjan 这个人大家可能会立刻联想起著名的强连通分量 tarjan 算法,然而这只是他提出的众多算法中的一个。本文会简单引用一些资料介绍 Robert Tarjan 这位伟大而高产的计算机科学家并简单介绍一下他提出的几个重要的算法与数据结构。
个人简历
Robert Tarjan在多所大学担任学术职务,如:康奈尔大学(1972-1973年),加州大学伯克利分校(1973-1975),斯坦福大学(1974-1980),纽约大学(1981-1985)。 他也加入过NEC研究所(1989-1997),并在美国麻省理工学院(1996年)担任Visiting Scientist 。
曾在AT&T贝尔实验室(1980-1989),浩信科技(1997-2001),康柏(2002年)和惠普(2006年至今)工作。 他曾加入ACM和IEEE委员会,并曾为几家期刊的编辑。
成就
Robert Tarjan设计了求解的应用领域的许多问题的广泛有效的算法和数据结构。
他已发表了超过228篇理论文章(包括杂志,一些书中的一些章节文章等)。Robert Tarjan以在数据结构和图论上的开创性工作而闻名。
他的一些著名的算法包括 Tarjan最近共同祖先离线算法 ,Tarjan的强连通分量算法以及Link-Cut-Trees算法等。其中Hopcroft-Tarjan平面嵌入算法是第一个线性时间平面算法。
Tarjan也开创了重要的数据结构如:斐波纳契堆和splay树(splay发明者还有Daniel Sleator)。另一项重大贡献是分析了并查集。他是第一个证明了计算反阿克曼函数的乐观时间复杂度的科学家。
奖项
Tarjan与约翰霍普克罗夫特共同于1986年获得图灵奖。
Tarjan还于1994年当选为ACM院士。
Tarjan其他奖项包括:
奈望林纳奖信息科学(1983第一个获奖者)
国家科学院的研究倡议奖 (1984)
巴黎Kanellakis奖-理论与实践( ACM1999)
帕斯卡奖章数学与计算机科学( 欧洲科学院2004)
加州理工学院杰出校友奖( 美国加州技术研究所2010)
一些重要的算法
Tarjan最近公共祖先
Tarjan 最近公共祖先离线算法可以以 O(log n) 的时间复杂度计算一棵树上两个节点的最近公共祖先。通过倍增的思想离线处理出树上每个点的深度差为 2 的幂次的祖先,询问的时候只要让两点跳到相同深度的祖先并向上寻找最近的公共祖先。
int lca(int x,int y){ if (dep[x]<dep[y]) swap(x,y); int t=dep[x]-dep[y]; for (int i=18;i>=0;i--) if ((1<<i)&t) x=fa[x][i]; for (int i=18;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; if (x==y) return x; return fa[x][0];}int dfs(int u){ for (int i=1;i<=18;i++) fa[u][i]=fa[fa[u][i-1]][i-1]; for (int j=head[u];j;j=e[j].pre){ int v=e[j].obj; if (v==fa[u][0]) continue; dep[v]=dep[u]+1; dfs(v); }}
Tarjan强连通分量
Tarjan 强连通算法是在 O(n) 的时间复杂度下找出一张有向图的所有的强联通分量。它利用了 dfs 与时间戳,维护了每个点的后继节点能访问到的最早的时间戳low,并通过 low 和 dfs 序来判断是否存在环。
stack<int> q;void tarjan(int u){ dfn[u]=low[u]=++idx; q.push(u); for (int j=head[u];j;j=e[j].pre){ int v=e[j].obj; if (!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else if (!bl[v]) low[u]=min(low[u],dfn[v]); } if (low[u]==dfn[u]){ int x=-1,cnt=0; ++scc; while (x!=u){ x=q.top(); q.pop(); bl[x]=scc; } }}
link-cut tree
link-cut tree是一个建立在 splay 上的算法。它可以支持树形态的转换,比如说合并两棵树,将树的一部分切去,寻找某个点当前所处树的根,并可以维护在树上的信息。link-cut tree的每个操作时间复杂度都是 O(log n) 的。值得一提的是 link-cut tree 和 splay 都是 Daniel Dominic Sleator 和 Robert Endre Tarjan 共同提出的。
void up(int x){ int l=c[x][0],r=c[x][1]; mx[x]=x; if (val[mx[l]]>val[mx[x]]) mx[x]=mx[l]; if (val[mx[r]]>val[mx[x]]) mx[x]=mx[r];}void rot(int x){ int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1; if (!isroot(y)){ if (c[z][0]==y) c[z][0]=x; else c[z][1]=x; } fa[x]=z; fa[y]=x; fa[c[x][r]]=y; c[y][l]=c[x][r]; c[x][r]=y; up(y); up(x);}void splay(int x){ int top=0; st[++top]=x; for (int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; for (int i=top;i;i--) Down(st[i]); while (!isroot(x)){ int y=fa[x],z=fa[y]; if (!isroot(y)){ if ((c[y][0]==x)^(c[z][0]==y)) rot(x); else rot(y); } rot(x); }}bool isroot(int x){ int y=fa[x]; if ((c[y][0]!=x)&&(c[y][1]!=x)) return 1; return 0;}void access(int x){ for (int t=0;x;x=fa[x]){ splay(x); c[x][1]=t; up(x); t=x; }}void makeroot(int x){ access(x); splay(x); rev[x]^=1; }void link(int x,int y){ makeroot(x); fa[x]=y;}void cut(int x,int y){ makeroot(x); access(y); splay(y); if (c[y][0]==x) c[y][0]=fa[x]=0;}void split(int x,int y){ makeroot(x); access(y); splay(y);}
结语
Tarjan 他老人家还提出过非常多实用高效的算法,鉴于本人的水平有限只能列举上述几个著名的算法。可以看出 Tarjan 对算法世界带来的巨大贡献。希望我们都能好好学习理解并应用 Tarjan 提出的众多算法,并学习他高产背后的科学精神。
- 高产的计算机科学家——Tarjan
- Robert E. Tarjan——杰出计算机科学家
- 计算机科学家的主页
- 中国的几个计算机科学家
- 高能(高产)预警 ———— 水博客
- 浪漫主义计算机科学家的真知灼见——《代码整洁之道》
- 悼念伟大的计算机科学家Dijkstra
- 科学家发现古希腊2000年前的计算机
- 计算机科学家常用的32个算法
- 计算机科学家常用的32个算法
- 推动计算机历史进程的15位顶尖计算机科学家
- 旱半夏的高产栽培要点
- 如何成为快乐高产的程序员
- 荷兰计算机科学家Dijkstra
- [转]悼念伟大的计算机科学家Edsger Wybe Dijkstra
- 悼念伟大的计算机科学家Edsger Wybe Dijkstra
- [转] 悼念伟大的计算机科学家Edsger Wybe Dijkstra
- [计算机科学家]高德纳:最年轻的图灵奖获得者
- C#基础视频教程7.5 如何编写简单游戏
- C#应用视频教程1.1 Socket通信基础
- Java中的static关键字
- C#应用视频教程1.2 Socket通信客户端实现
- 系统中文件的传输
- 高产的计算机科学家——Tarjan
- C#应用视频教程1.4 实现完整以太网通讯
- Android--kotlin语言学习资源
- C#应用视频教程1.3 Socket通信客户端完善
- C#应用视频教程2.1 OPENGL虚拟仿真介绍
- C#应用视频教程2.2 OPENGL虚拟仿真介绍
- #define与enum的区别
- C#应用视频教程2.3 OPENGL虚拟仿真介绍
- C#应用视频教程2.4 OPENGL虚拟仿真介绍