Traditional Ways of Tree Traversal

This page contains examples of some “standard” traversal algorithms (ones that can be found in most textbooks). All examples perform pre-order tree traversal on a general rooted tree. “Algorithms, Data Structures and Problem Solving with C++” by Mark Allen Weiss (Addison-Wesley, 1995) gives the following definition of the general rooted tree:

  • One node is distinguished as a root.
  • Every node c, except the root, is connected by an edge from exactly one other node p. p is the parent and c is one of p‘s children.
  • There is a unique path from the root to each node. The number of edges that must follow is the path length (sometimes it is called “depth”).

Binary trees and their variations (AVL, red-black and so forth) are not considered here.

Each example performs full traversal of a DOM tree and prints name and value of each node. An XML parser, for example Apache’s Xerces, is needed in order to run the code.

Example 1. Traversal using recursion

Recursive traversal is the best known and most frequently used. Recursive algorithm uses method call stack in order to keep the state of the traversal for every level of a tree. There is a common misconception that recursive algorithms are slow because of the call stack copying overhead. I have not found it to be the case in Java, at least it is not the case for methods with small number of local variables.



import org.w3c.dom.*;

public class RecursiveTraversal implements ITraversal {

  /**
* Performs full tree traversal using recursion.
*/
public void traverse( Node parentNode ) {
// traverse all nodes that belong to the parent
for(Node node=parentNode.getFirstChild(); node!=null; node=node.getNextSibling()
) {
// print node information
System.out.println( node.getNodeName()+"="+node.getNodeValue());
// traverse children
traverse(node);
}
}
}

Example 2. Traversal using stack

A stack object is used to store tree level’s state thus eliminating the need for recursion.

Note that in reality you don’t want to use java.util.Stack because its methods are synchronized. It also inherits from Vector and its methods are synchronized as well. So some sort of custom stack class (for example, based on java.util.ArrayList) should be used instead.



import org.w3c.dom.*;
import java.util.*; public class StackTraversal implements ITraversal { /**
* Performs full tree traversal using stack.
*/
public void traverse( Node rootNode ) { Stack stack = new Stack();
// ignore root -- root acts as a container
Node node=rootNode.getFirstChild(); while (node!=null) {
// print node information
System.out.println( node.getNodeName()+"="+node.getNodeValue()); if ( node.hasChildNodes()) {
// store next sibling in the stack. We return to it after all children are
processed.
if (node.getNextSibling()!=null)
stack.push( node.getNextSibling() );
node = node.getFirstChild();
}
else {
node = node.getNextSibling();
if (node==null && !stack.isEmpty())
// return to the parent's level.
// note that some levels can be skipped if the parent's node was the last one.
node=(Node) stack.pop();
}
}
}
}

Example 3. Traversal using child-parent link

It is possible to avoid using stack for treelike structures that provide support for child-parent link. Link from child to parent can be used to return back to the parent level once the child level is processed. This link effectively simulates stack, so there is no need for a separate stack object. Most of the tree types (including DOM) do support child-parent link. This is probably the most elegant way of traversing a tree — no recursion or stack is involved.



import org.w3c.dom.*;

public class LinkTraversal implements ITraversal {

  /**
* Performs full tree traversal using child-parent link.
*/
public void traverse( Node rootNode ) { // ignore root -- root acts as a container
Node node=rootNode.getFirstChild(); while (node!=null) {
// print node information
System.out.println( node.getNodeName()+"="+node.getNodeValue()); if ( node.hasChildNodes()) {
node = node.getFirstChild();
}
else { // leaf
// find the parent level
while (node.getNextSibling()==null && node != rootNode)
// use child-parent link to get to the parent level
node=node.getParentNode(); node = node.getNextSibling();
}
}
}
}

Tree 使用方式的更多相关文章

  1. EasyUI Tree递归方式获取JSON

    最近需要用到EASYUI中的TREE功能,以前我是直接拼接成<UL><LI>发现这样拼完之后在更改树后对树的刷新不是很理想,现改用JSON格式,首先分析TREE中JOSN格式如 ...

  2. 数据结构 - Codeforces Round #353 (Div. 2) D. Tree Construction

    Tree Construction Problem's Link ------------------------------------------------------------------- ...

  3. Device Tree(三):代码分析【转】

    转自:http://www.wowotech.net/linux_kenrel/dt-code-analysis.html Device Tree(三):代码分析 作者:linuxer 发布于:201 ...

  4. Device Tree(三):代码分析

    一.前言 Device Tree总共有三篇,分别是: 1.为何要引入Device Tree,这个机制是用来解决什么问题的?(请参考引入Device Tree的原因) 2.Device Tree的基础概 ...

  5. 【转】Device Tree(三):代码分析

    原文网址:http://www.wowotech.net/linux_kenrel/dt-code-analysis.html 一.前言 Device Tree总共有三篇,分别是: 1.为何要引入De ...

  6. XGBoost 与 Boosted Tree

    http://www.52cs.org/?p=429 作者:陈天奇,毕业于上海交通大学ACM班,现就读于华盛顿大学,从事大规模机器学习研究. 注解:truth4sex  编者按:本文是对开源xgboo ...

  7. 转 Velocity中加载vm文件的三种方式

    Velocity中加载vm文件的三种方式   velocitypropertiespath Velocity中加载vm文件的三种方式:    方式一:加载classpath目录下的vm文件 Prope ...

  8. orocos_kdl学习(二):KDL Tree与机器人运动学

    KDL(Kinematics and Dynamics Library)中定义了一个树来代表机器人的运动学和动力学参数,ROS中的kdl_parser提供了工具能将机器人描述文件URDF转换为KDL ...

  9. Boosted Tree

    原文:http://www.52cs.org/?p=429 作者:陈天奇,毕业于上海交通大学ACM班,现就读于华盛顿大学,从事大规模机器学习研究. 注解:truth4sex  编者按:本文是对开源xg ...

随机推荐

  1. 网狐6603 cocos2dx 棋牌、捕鱼、休闲类游戏《李逵捕鱼》手机端完整源码分析及分享

    该资源说明: cocos2d 棋牌.捕鱼.休闲类游戏<李逵捕鱼>手机端完整源码,网狐6603配套手机版源码,可以选桌子,适合新手学习参考,小编已亲测试,绝对完整可编译手机端,下载后将文件考 ...

  2. css 单位 px em rem

    http://www.cnblogs.com/leejersey/p/3662612.html

  3. Readonly and other things about C++

    1. in c# readonly can be delayed to initialize in constructor. 2. in c++ totally no readonly. Many p ...

  4. Activiti工作流学习-----基于5.19.0版本(3)

    前面关于eventType的属性值的配置简单的说了一下,activiti支持的值如下表所示:这是我摘抄的activiti官网的 Event 的名字 描述 Event的类名 ENGINE_CREATED ...

  5. java事件响应方法汇总(容器类监听、监听器类、AbstractAction、反射)

    Java图形用户界面中,处理事件时所必须的步骤是: 1.创建接受响应的组件(控件)2.实现相关事件监听接口3.注册事件源的动作监听器4.事件触发时的事件处理 相应的可以通过以下的集中方式来作出事件响应 ...

  6. Codeforces 163A Substring and Subsequence

    http://codeforces.com/problemset/problem/163/A?mobile=true 题目大意:给出两个串,问a的连续子串和b的子串(可以不连续)相同的个数. 思路:在 ...

  7. TranslateAnimation详解

    TranslateAnimation详解 Android JDK为我们提供了4种动画效果,分别是: AlphaAnimation,RotateAnimation, ScaleAnimation, Tr ...

  8. bzoj1190

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1190 神题...... F[i][j]表示容量为j*2^i+W第i-1位到第0位的最大价值, ...

  9. 【剑指offer】面试题40:数组中只出现一次的数字

    题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: 因为只有两个只出现一次的数字,所以所有数字进行异或之后得到值res一定不是0.这样,res ...

  10. Ajax--json(Ajax调用返回json封装代码、格式及注意事项)

    Ajax调用json封装代码<dbda.php>: //Ajax调用返回JSON public function JsonQuery($sql,$type=1,$db="mydb ...