- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
最近公共祖先LCA、打印螺旋矩阵.doc
最近公共祖先LCA、打印螺旋矩阵?解答这个问题之前,咱们得先搞清楚到底什么是最近公共祖先。最近公共祖先简称LCA,所谓LCA,是当给定一个有根树T时,对于任意两个结点u、v,找到一个离根最远的结点x,使得x同时是u和v的祖先,x 便是u、v的最近公共祖先。
? ? 举个例子,如针对下图所示的一棵普通的二叉树来讲:
? ? 结点3和结点4的最近公共祖先是结点2,即LCA(3 4)=2 。在此,需要注意到当两个结点在同一棵子树上的情况,如结点3和结点2的最近公共祖先为2,即 LCA(3 2)=2。同理:LCA(5 6)=4,LCA(6 10)=1。
? ? 明确了题意,咱们便来试着解决这个问题。一般文章的做法,可能是针对是否为二叉查找树分情况讨论,想必这也是一般人最先想到的思路。除此之外,还有所谓的Tarjan算法、倍增算法、以及转换为RMQ问题(求某段区间的极值)。
? ? 下面,便来一一具体阐述这几种方法。
解法一、暴力对待
1.1、是二叉查找树
? ? 在当这棵树是二叉查找树的情况下,如下图:
? ? 那么从树根开始:
如果当前结点t 大于结点u、v,说明u、v都在t 的左侧,所以它们的共同祖先必定在t 的左子树中,故从t 的左子树中继续查找;
如果当前结点t 小于结点u、v,说明u、v都在t 的右侧,所以它们的共同祖先必定在t 的右子树中,故从t 的右子树中继续查找;
如果当前结点t 满足 u t v,说明u和v分居在t 的两侧,故当前结点t 即为最近公共祖先;
而如果u是v的祖先,那么返回u的父结点,同理,如果v是u的祖先,那么返回v的父结点。
? 代码如下所示:
//copyright@eriol?2011??
//modified?by?July?2014??
public?int?query(Node?t,?Node?u,?Node?v)?{????
????int?left?=?u.value;????
????int?right?=?v.value;????
????Node?parent?=?null;????
??
????//二叉查找树内,如果左结点大于右结点,不对,交换??
????if?(left??right)?{????
????????int?temp?=?left;????
????????left?=?right;????
????????right?=?temp;????
????}????
??
????while?(true)?{????
????????//如果t小于u、v,往t的右子树中查找??
????????if?(t.value??left)?{????
????????????parent?=?t;????
????????????t?=?t.right;????
??
????????//如果t大于u、v,往t的左子树中查找??
????????}?else?if?(t.value??right)?{????
????????????parent?=?t;????
????????????t?=?t.left;????
????????}?else?if?(t.value?==?left?||?t.value?==?right)?{????
????????????return?parent.value;????
????????}?else?{????
????????????return?t.value;????
????????}????
????}????
}????
1.2、不是二叉查找树
? ? 但如果这棵树不是二叉查找树呢?一网友何海涛在他博客中用了一种蛮力方法。由于每个结点都有一个指针指向它的父结点,于是我们可以从任何一个结点出发,得到一个到达树根结点的单向链表。因此这个问题转换为两个单向链表的第一个公共结点。
? ? 我不想再在这里重复赘述,有兴趣的可以看原文。
? ? 接下来的解法,将不再区别对待是否为二叉查找树,而是一致当做是一棵普通的二叉树。总体来说,由于可以把LCA问题看成是询问式的,即给出一系列询问,程序对每一个询问尽快做出反应。故处理这类问题一般有两种解决方法:
一种是在线算法,相当于循序渐进处理;
另外一种则是离线算法,如Tarjan算法,相当于一次性批量处理。
解法二、Tarjan算法
? ? 如上文末节所述,不论咱们所面对的二叉树是二叉查找树,或不是二叉查找树,都可以把求任意两个结点的最近公共祖先,当做是查询的问题,如果是只求一次,则是单次查询;如果要求多个任意两个结点的最近公共祖先,则相当于是批量查询。
? ? 涉及到批量查询的时候,咱们可以借鉴离线处理的方式,这就引出了解决此LCA问题的Tarjan离线算法。
2.1、什么
文档评论(0)