玩转遍历树

本书不是一本关于Python编程的书,因为主题太广泛了。话虽如此,但对于Python的入门书籍来说,详细讨论递归编程并不常见;而递归编程技术通常很适合处理树;递归编程也具有函数式编程语言风格的通用编程策略,在执行并行开发时非常有用。读者可以在处理非常大的数据集时采用它们进行开发。

系统发生树的概念与计算机科学略有不同。系统发生树可以是有根树(这时它们具有正常的树数据结构)或是无根树,后者它们可用无向的非循环图表示。系统发生树的边也可以有权重。因此,在阅读文档时请注意这一点;如果内容是由系统发生学家编写的,那么读者可以这样理解树(有根和无根),而大多数其他文档将使用无向无环图来表示无根树。话虽如此,在本秘笈中,将假设所有的树都是有根的。

最后请注意,虽然这里的秘笈主要是为了帮助读者理解递归算法和树结构,但最后一部分实际上非常实用的,且对于下一个秘笈的使用至关重要。在这里插入图片描述如何做
参看下列步骤:
1,首先,加载RAxML产生的所有埃博拉病毒的树,如下在这里插入图片描述2,然后,计算每个节点的级别(即到达根节点的距离):在这里插入图片描述
。 DendroPy的节点对象有一个叫level的方法,它是用来比较用的,但这里将介绍一种递归算法,我们将用它来实现。
。请注意该函数是如何工作的:它是从seed_node开始调用的,该节点是在我们假设处理有根树的根节点。根节点默认的级别是0。该函数再对它的所有子节点调用函数自身,同时把级别加一。然后,对每一个非叶节点(也就是内节点),重复这个调用过程,直到递归至到达叶节点。
。对于如果是叶节点,那么就打印输出该叶节点的级别(当然我们也可以对内节点同样这么做),结果显示和DendroPy的内部函数输出具有相同的信息。
3,进而,计算每个节点的高度,某个节点的高度是从该节点开始的最大向下路径(即到达叶节点)的边的数目,如下所示:在这里插入图片描述
这里,我们将使用相同的递归策略,每个节点将返回它到它父节点的高度;如果该节点为叶节点,其高度为0;否则其高度值将是所有子节点的高度的最大值加上
请注意这里用到一个map函数作用在一个lambda函数上,它用来得到当前节点的所有子节点的所有的高度值;然后选择它们中的最大值,这里的max函数实现了一种归约(reduce)的功能,它能够对所有报告的值进行总结。如果读者能把该过程和MapReduce框架联系起来,你就想对了;这些就是受到了函数式编程语言风格的启发
4,现在计算每个节点的子节点,这点应该很容易理解:
在这里插入图片描述5,这里打印输出所有的叶子节点,这看上去是显而易见的:
在这里插入图片描述
请注意至今为止我们开发的所有函数都对树使用了一种非常清楚的遍历模式:读者先调用第一个子代,然后子代再调用它的子代,以此类推;只有在此之后,你才可以用深度优先(depth-first)的模式调用下一个子代,但是我们可以用不同的模式进行遍历。
6,现在用广度优先(breath-first)的方式打印输出叶节点,即这里将首先打印那些具有低级别的节点(距离根节点较近的节点),如下所示:在这里插入图片描述
在解释该算法前,让我们先看看这个运行结果和前一个结果有什么不同。对初学者来说,看一下后面的图。如果用深度优先顺序,会得到Y、A、X、B和C;而如果用广度优先,将得到X、B、C、Y和A。不同的遍历模式将影响节点是如何被访问的,这通常很重要。
关于前面的代码,这里将用一种完全不同的策略来实现迭代算法,我们将采用先进先出(FIFO,First-in First-out)的队列(queue)来排序节点。请注意Python的deque可以有效率的实现先进先出,也可以实现后进先出(LIFO,Last-in First-out),这是因为它采用了有效率的数据结构对队列的两端处理都很好。
该算法从把根节点放入队列开始,当队列非空时,从队列前端提取节点,如果它是内部节点,就把该节点的所有子节点放到队列后边。
我们将迭代这个过程,直到队列为空。强烈建议读者用笔和纸画图记录该例子,理解这个例子的实现,这里的代码虽然短小,但不是很简单。在这里插入图片描述
7,让我们回到真实的数据集。由于这里有太多的数据要可视化,我们将产生一个剪裁后的版本,这里我们去除了一些具有同一的病毒种的子树;在EBOV的例子中,是具有同一爆发期的子树。同时这里还对树进行了阶梯化(ladderize ),也即对子节点按照其子节点数目进行排序:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值