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 pp 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. MVC中,加入的一个aspx页面用到AspNetPager控件处理办法

    今天项目遇到了如题所示的问题,按照官方的案例介绍做分页,简直要奔溃了, 使用URL重写,但是page总是1,根本不跳, 不使用URL重写,又出现,第一页是 http://aa.com/view_asp ...

  2. Python番外 事务 那些事

    Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一般就不做了,要么做完,要么就不做.也就是说,事务必须是一 ...

  3. C++异常处理小例

      学习程序的好方法是阅读代码和改进代码.下面的程例来自<An Overview of the C++ Programming Language>(5.1 异常和错误处理)程序用途:使用C ...

  4. 面试题 46 1+ 2+3+...+n

    class Temp{ public: Temp(){ ++N; sum+=N; } static void Reset(){ N = ; sum = ; } static int getSum(){ ...

  5. Leetcode_ Best Time to Buy and Sell Stock II

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  6. bash与sh的区别

    在shell脚本的开头往往有一句话来定义使用哪种sh解释器来解释脚本.目前研发送测的shell脚本中主要有以下两种方式:(1) #!/bin/sh(2) #!/bin/bash在这里求教同福客栈的各位 ...

  7. CONTEST45 呵呵呵呵呵

    题目质量差评!为什么不给数据范围! A.乘积最大3 题目:http://dev.luogu.org/problem/show?pid=2172 题解:sb题,均值定理. 代码: #include< ...

  8. BZOJ1532: [POI2005]Kos-Dicing

    1532: [POI2005]Kos-Dicing Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1060  Solved: 321[Submit][St ...

  9. javaweb 登录注册

    1:用户登录界面 login.jsp <%@ page language="java" import="java.util.*" pageEncoding ...

  10. PYCHARM配置文件如何导入

    请到此下载,如下: http://share.weiyun.com/c00040649e85c4ab1dbc47a0fe9a0a7a 或者:http://files.cnblogs.com/files ...