树的遍历方式
树的遍历
(一)树结构实现
- package tree.tree;
- import java.util.Iterator;
- import java.util.List;
- /**
- * 树节点抽象接口
- *
- * @author jzj
- * @data 2009-12-17
- */
- public abstract class TreeNode implements Comparable {
- //父节点
- private TreeNode pNode;
- //数据域,节点编号,不能修改
- private int nodeId;
- //数据域,节点名字,能修改
- private String nodeName;
- //节点深度,根默认为0
- private int depth;
- public TreeNode getPMenuComponent() {
- return pNode;
- }
- public void setPMenuComponent(TreeNode menuComponent) {
- pNode = menuComponent;
- }
- public int getNodeId() {
- return nodeId;
- }
- public void setNodeId(int nodeId) {
- this.nodeId = nodeId;
- }
- public String getNodeName() {
- return nodeName;
- }
- public void setNodeName(String nodeName) {
- this.nodeName = nodeName;
- }
- public int getDepth() {
- return depth;
- }
- public void setDepth(int depth) {
- this.depth = depth;
- }
- //添加子节点 默认不支持,叶子节点不支持此功能
- public void addSubNode(TreeNode menuComponent) {
- throw new UnsupportedOperationException();
- }
- //删除子节点 默认不支持,叶子节点不支持此功能
- public void removeSubNode(TreeNode menuComponent) {
- throw new UnsupportedOperationException();
- }
- //修改节点信息
- public void modiNodeInfo(String nodeName) {
- this.setNodeName(nodeName);
- }
- //获取子节点 默认不支持,叶子节点不支持此功能
- public List getSubNodes() {
- throw new UnsupportedOperationException();
- }
- //打印节点信息
- public void print() {
- throw new UnsupportedOperationException();
- }
- //获取节点信息
- protected abstract StringBuffer getNodeInfo();
- //提供深度迭代器 默认不支持,叶子节点不支持此功能
- public Iterator createDepthOrderIterator() {
- throw new UnsupportedOperationException();
- }
- //提供广度优先迭代器 默认不支持,叶子节点不支持此功能
- public Iterator createLayerOrderIterator() {
- throw new UnsupportedOperationException();
- }
- /**
- * 根据树节点id,在当然节点与子节点中搜索指定的节点
- * @param treeId
- * @return TreeNode
- */
- public TreeNode getTreeNode(int treeId) {
- return getNode(this, treeId);
- }
- /**
- * 使用树的先序遍历递归方式查找指定的节点
- *
- * @param treeNode 查找的起始节点
- * @param treeId 节点编号
- * @return
- */
- protected TreeNode getNode(TreeNode treeNode, int treeId) {
- throw new UnsupportedOperationException();
- }
- public int compareTo(Object o) {
- TreeNode temp = (TreeNode) o;
- return this.getNodeId() > temp.getNodeId() ? 1 : (this.getNodeId() < temp
- .getNodeId() ? -1 : 0);
- }
- public boolean equals(Object menuComponent) {
- if (!(menuComponent instanceof TreeNode)) {
- return false;
- }
- TreeNode menu = (TreeNode) menuComponent;
- // 如果两个节点的nodeID相应则认为是同一节点
- return this.getNodeId() == menu.getNodeId();
- }
- }
package tree.tree; import java.util.Iterator; import java.util.List; /** * 树节点抽象接口 * * @author jzj * @data 2009-12-17 */ public abstract class TreeNode implements Comparable { //父节点 private TreeNode pNode; //数据域,节点编号,不能修改 private int nodeId; //数据域,节点名字,能修改 private String nodeName; //节点深度,根默认为0 private int depth; public TreeNode getPMenuComponent() { return pNode; } public void setPMenuComponent(TreeNode menuComponent) { pNode = menuComponent; } public int getNodeId() { return nodeId; } public void setNodeId(int nodeId) { this.nodeId = nodeId; } public String getNodeName() { return nodeName; } public void setNodeName(String nodeName) { this.nodeName = nodeName; } public int getDepth() { return depth; } public void setDepth(int depth) { this.depth = depth; } //添加子节点 默认不支持,叶子节点不支持此功能 public void addSubNode(TreeNode menuComponent) { throw new UnsupportedOperationException(); } //删除子节点 默认不支持,叶子节点不支持此功能 public void removeSubNode(TreeNode menuComponent) { throw new UnsupportedOperationException(); } //修改节点信息 public void modiNodeInfo(String nodeName) { this.setNodeName(nodeName); } //获取子节点 默认不支持,叶子节点不支持此功能 public List getSubNodes() { throw new UnsupportedOperationException(); } //打印节点信息 public void print() { throw new UnsupportedOperationException(); } //获取节点信息 protected abstract StringBuffer getNodeInfo(); //提供深度迭代器 默认不支持,叶子节点不支持此功能 public Iterator createDepthOrderIterator() { throw new UnsupportedOperationException(); } //提供广度优先迭代器 默认不支持,叶子节点不支持此功能 public Iterator createLayerOrderIterator() { throw new UnsupportedOperationException(); } /** * 根据树节点id,在当然节点与子节点中搜索指定的节点 * @param treeId * @return TreeNode */ public TreeNode getTreeNode(int treeId) { return getNode(this, treeId); } /** * 使用树的先序遍历递归方式查找指定的节点 * * @param treeNode 查找的起始节点 * @param treeId 节点编号 * @return */ protected TreeNode getNode(TreeNode treeNode, int treeId) { throw new UnsupportedOperationException(); } public int compareTo(Object o) { TreeNode temp = (TreeNode) o; return this.getNodeId() > temp.getNodeId() ? 1 : (this.getNodeId() < temp .getNodeId() ? -1 : 0); } public boolean equals(Object menuComponent) { if (!(menuComponent instanceof TreeNode)) { return false; } TreeNode menu = (TreeNode) menuComponent; // 如果两个节点的nodeID相应则认为是同一节点 return this.getNodeId() == menu.getNodeId(); } }
- package tree.tree;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- /**
- * 树的分支节点
- *
- * @author jzj
- * @data 2009-12-17
- */
- public class TreeBranchNode extends TreeNode {
- //存储子节点
- List subNodesList = new ArrayList();
- public TreeBranchNode(int nodeId, String nodeName) {
- this.setNodeId(nodeId);
- this.setNodeName(nodeName);
- }
- //添加子节点
- public void addSubNode(TreeNode menuComponent) {
- // 设置父节点
- menuComponent.setPMenuComponent(this);
- // 设置节点的深度
- menuComponent.setDepth(this.getDepth() + 1);
- subNodesList.add(menuComponent);
- }
- //删除一个子节点
- public void removeSubNode(TreeNode menuComponent) {
- subNodesList.remove(menuComponent);
- }
- //获取子节点
- public List getSubNodes() {
- return subNodesList;
- }
- //打印节点信息,以树的形式展示,所以它包括了所有子节点信息
- public void print() {
- System.out.println(this.getNodeInfo());
- }
- //打印节点本身信息,不递归打印子节点信息
- public String toString() {
- return getSefNodeInfo().toString();
- }
- // 递归打印节点信息实现
- protected StringBuffer getNodeInfo() {
- StringBuffer sb = getSefNodeInfo();
- sb.append(System.getProperty("line.separator"));
- //如果有子节点
- for (Iterator iter = subNodesList.iterator(); iter.hasNext();) {
- TreeNode node = (TreeNode) iter.next();
- //递归打印子节点信息
- sb.append(node.getNodeInfo());
- if (iter.hasNext()) {
- sb.append(System.getProperty("line.separator"));
- }
- }
- return sb;
- }
- //节点本身信息,不含子节点信息
- private StringBuffer getSefNodeInfo() {
- StringBuffer sb = new StringBuffer();
- // 打印缩进
- for (int i = 0; i < this.getDepth(); i++) {
- sb.append(' ');
- }
- sb.append("+--");
- sb.append("[nodeId=");
- sb.append(this.getNodeId());
- sb.append(" nodeName=");
- sb.append(this.getNodeName());
- sb.append(']');
- return sb;
- }
- //为外界提供遍历组合结构的迭代器
- public Iterator createDepthOrderIterator() {
- return new TreeOutOrder.DepthOrderIterator(this);
- }
- //为外界提供遍历组合结构的迭代器
- public Iterator createLayerOrderIterator() {
- return new TreeOutOrder.LevelOrderIterator(this);
- }
- /**
- * 使用树的先序遍历递归方式查找指定的节点
- *
- * @param treeNode 查找的起始节点
- * @param treeId 节点编号
- * @return
- */
- protected TreeNode getNode(TreeNode treeNode, int treeId) {
- //如果找到,则停止后续搜索,并把查找到的节点返回给上层调用者
- if (treeNode.getNodeId() == treeId) {//1、先与父节点比对
- return treeNode;
- }
- TreeNode tmp = null;
- //如果为分支节点,则遍历子节点
- if (treeNode instanceof TreeBranchNode) {
- for (int i = 0; i < treeNode.getSubNodes().size(); i++) {//2、再与子节点比对
- tmp = getNode((TreeNode) treeNode.getSubNodes().get(i), treeId);
- if (tmp != null) {//如果查找到,则返回上层调用者
- return tmp;
- }
- }
- }
- //如果没有找到,返回上层调用者
- return null;
- }
- }
package tree.tree; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * 树的分支节点 * * @author jzj * @data 2009-12-17 */ public class TreeBranchNode extends TreeNode { //存储子节点 List subNodesList = new ArrayList(); public TreeBranchNode(int nodeId, String nodeName) { this.setNodeId(nodeId); this.setNodeName(nodeName); } //添加子节点 public void addSubNode(TreeNode menuComponent) { // 设置父节点 menuComponent.setPMenuComponent(this); // 设置节点的深度 menuComponent.setDepth(this.getDepth() + 1); subNodesList.add(menuComponent); } //删除一个子节点 public void removeSubNode(TreeNode menuComponent) { subNodesList.remove(menuComponent); } //获取子节点 public List getSubNodes() { return subNodesList; } //打印节点信息,以树的形式展示,所以它包括了所有子节点信息 public void print() { System.out.println(this.getNodeInfo()); } //打印节点本身信息,不递归打印子节点信息 public String toString() { return getSefNodeInfo().toString(); } // 递归打印节点信息实现 protected StringBuffer getNodeInfo() { StringBuffer sb = getSefNodeInfo(); sb.append(System.getProperty("line.separator")); //如果有子节点 for (Iterator iter = subNodesList.iterator(); iter.hasNext();) { TreeNode node = (TreeNode) iter.next(); //递归打印子节点信息 sb.append(node.getNodeInfo()); if (iter.hasNext()) { sb.append(System.getProperty("line.separator")); } } return sb; } //节点本身信息,不含子节点信息 private StringBuffer getSefNodeInfo() { StringBuffer sb = new StringBuffer(); // 打印缩进 for (int i = 0; i < this.getDepth(); i++) { sb.append(' '); } sb.append("+--"); sb.append("[nodeId="); sb.append(this.getNodeId()); sb.append(" nodeName="); sb.append(this.getNodeName()); sb.append(']'); return sb; } //为外界提供遍历组合结构的迭代器 public Iterator createDepthOrderIterator() { return new TreeOutOrder.DepthOrderIterator(this); } //为外界提供遍历组合结构的迭代器 public Iterator createLayerOrderIterator() { return new TreeOutOrder.LevelOrderIterator(this); } /** * 使用树的先序遍历递归方式查找指定的节点 * * @param treeNode 查找的起始节点 * @param treeId 节点编号 * @return */ protected TreeNode getNode(TreeNode treeNode, int treeId) { //如果找到,则停止后续搜索,并把查找到的节点返回给上层调用者 if (treeNode.getNodeId() == treeId) {//1、先与父节点比对 return treeNode; } TreeNode tmp = null; //如果为分支节点,则遍历子节点 if (treeNode instanceof TreeBranchNode) { for (int i = 0; i < treeNode.getSubNodes().size(); i++) {//2、再与子节点比对 tmp = getNode((TreeNode) treeNode.getSubNodes().get(i), treeId); if (tmp != null) {//如果查找到,则返回上层调用者 return tmp; } } } //如果没有找到,返回上层调用者 return null; } }
- package tree.tree;
- /**
- * 树的叶子节点
- *
- * @author jzj
- * @data 2009-12-17
- *
- */
- public class TreeLeafNode extends TreeNode {
- public TreeLeafNode(int nodeId, String nodeName) {
- this.setNodeId(nodeId);
- this.setNodeName(nodeName);
- }
- // 获取叶子节点信息
- protected StringBuffer getNodeInfo() {
- StringBuffer sb = new StringBuffer();
- // 打印缩进
- for (int i = 0; i < this.getDepth(); i++) {
- sb.append(' ');
- }
- sb.append("---");
- sb.append("[nodeId=");
- sb.append(this.getNodeId());
- sb.append(" nodeName=");
- sb.append(this.getNodeName());
- sb.append(']');
- return sb;
- }
- public String toString() {
- return getNodeInfo().toString();
- }
- }
package tree.tree; /** * 树的叶子节点 * * @author jzj * @data 2009-12-17 * */ public class TreeLeafNode extends TreeNode { public TreeLeafNode(int nodeId, String nodeName) { this.setNodeId(nodeId); this.setNodeName(nodeName); } // 获取叶子节点信息 protected StringBuffer getNodeInfo() { StringBuffer sb = new StringBuffer(); // 打印缩进 for (int i = 0; i < this.getDepth(); i++) { sb.append(' '); } sb.append("---"); sb.append("[nodeId="); sb.append(this.getNodeId()); sb.append(" nodeName="); sb.append(this.getNodeName()); sb.append(']'); return sb; } public String toString() { return getNodeInfo().toString(); } }
(二)利用树本身特点进行递归遍历(属内部遍历)
树的内部遍历方式有两种:前序遍历、后序遍历,注,没有中序遍历。与二叉树的内部遍历方式一样也是采用递归方式实现的。
- package tree.tree;
- /**
- * 树的两种 内部 遍历方式:前序遍历、后序遍历
- *
- * @author jzj
- * @data 2009-12-17
- */
- public class TreeInOrder {
- /**
- * 树的前序递归遍历 pre=prefix(前缀)
- * @param node 要遍历的节点
- */
- public static void preOrder(TreeNode node) {
- //如果传进来的节点不为空,则遍历,注,叶子节点的子节点为null
- if (node != null) {
- System.out.print(node.getNodeId() + " ");//先遍历父节点
- if (node instanceof TreeBranchNode) {
- for (int i = 0; i < node.getSubNodes().size(); i++) {
- preOrder((TreeNode) node.getSubNodes().get(i));//再遍历子节点
- }
- }
- }
- }
- /**
- * 树的后序递归遍历 post=postfix(后缀)
- * @param node 要遍历的节点
- */
- public static void postOrder(TreeNode node) {
- //如果传进来的节点不为空,则遍历
- if (node != null) {
- //如果为分支节点,则遍历子节点
- if (node instanceof TreeBranchNode) {
- for (int i = 0; i < node.getSubNodes().size(); i++) {
- postOrder((TreeNode) node.getSubNodes().get(i));//先遍历子节点
- }
- }
- System.out.print(node.getNodeId() + " ");//后遍历父节点
- }
- }
- }
package tree.tree; /** * 树的两种 内部 遍历方式:前序遍历、后序遍历 * * @author jzj * @data 2009-12-17 */ public class TreeInOrder { /** * 树的前序递归遍历 pre=prefix(前缀) * @param node 要遍历的节点 */ public static void preOrder(TreeNode node) { //如果传进来的节点不为空,则遍历,注,叶子节点的子节点为null if (node != null) { System.out.print(node.getNodeId() + " ");//先遍历父节点 if (node instanceof TreeBranchNode) { for (int i = 0; i < node.getSubNodes().size(); i++) { preOrder((TreeNode) node.getSubNodes().get(i));//再遍历子节点 } } } } /** * 树的后序递归遍历 post=postfix(后缀) * @param node 要遍历的节点 */ public static void postOrder(TreeNode node) { //如果传进来的节点不为空,则遍历 if (node != null) { //如果为分支节点,则遍历子节点 if (node instanceof TreeBranchNode) { for (int i = 0; i < node.getSubNodes().size(); i++) { postOrder((TreeNode) node.getSubNodes().get(i));//先遍历子节点 } } System.out.print(node.getNodeId() + " ");//后遍历父节点 } } }
(三)利用栈与队列对树进行非递归遍历(属外部遍历)
树的两种外部非递归遍历方式:深度优先(即先根)遍历、广度优先(即层次)遍历。它们需借助于栈与队列来实现。
- package tree.tree;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.Stack;
- import queue.LinkedQueue;
- public class TreeOutOrder {
- /**
- * 深度优先遍历迭代器
- *
- * @author jzj
- * @data 2009-12-17
- */
- public static class DepthOrderIterator implements Iterator {
- //栈,用来深度遍历树节点,以便回溯
- Stack stack = new Stack();
- public DepthOrderIterator(TreeNode rootNode) {
- ArrayList list = new ArrayList();
- list.add(rootNode);
- // 将根节点迭代器入栈
- stack.push(list.iterator());
- }
- //是否有下一元素
- public boolean hasNext() {
- // 如果栈为空则返回,证明没有可遍历的元素
- if (stack.empty()) {
- return false;
- } else {
- // 如果栈不为空,则取出栈顶元素(迭代器)
- Iterator iterator = (Iterator) stack.peek();
- // 这里使用简单元素(即线性排列的元素,而不是树状结构的元素)的方式来遍历
- if (!iterator.hasNext()) {
- // 如果取出迭代器已经遍历完成,则弹出迭代器,以便回退到上一(父)迭代器继续开妈以深度优先方式遍历
- stack.pop();
- // 通过递归方式继续遍历父迭代器还未遍历到的节点元素
- return hasNext();
- } else {
- // 如果找到了下一个元素,返回true
- return true;
- }
- }
- }
- // 取下一元素
- public Object next() {
- // 如果还有下一个元素,则先取到该元素所对应的迭代器引用,以便取得该节点元素
- if (hasNext()) {
-
发表评论
相关推荐
### 多叉树遍历与结构解析 #### 概述 多叉树作为一种重要的数据结构,在计算机科学领域有着广泛的应用。本文将详细介绍一种基于C++实现的多叉树容器类`tree.hh`,该库由Kasper Peeters开发,并遵循GNU通用公共许可...
四叉树遍历是理解和操作四叉树的核心技术之一。遍历通常指的是按照某种顺序访问树的所有节点。在四叉树中,有几种常见的遍历方法,包括前序遍历(先访问根节点,再遍历子节点)、中序遍历(对于二叉树常用,但四叉树...
总之,`CTreeCtrl`的目录树遍历是Windows编程中的常见任务,它可以通过循环或递归方式实现。循环遍历简单直观,适用于对所有节点执行相同操作;而递归遍历则更加灵活,能适应更复杂的逻辑。在实际开发中,应根据需求...
而对于多叉树,由于其子节点数量的不确定性,遍历方式会有所不同,但基本思想是相同的,即确保每个节点都被访问一次且仅被访问一次。 1. **深度优先遍历**(DFS, Depth-First Search): - **前序遍历**:先访问根...
除了这些基本的遍历方式,还有其他变种,例如层序遍历(Level Order Traversal),也称为宽度优先搜索(BFS),从根节点开始,按层次依次访问所有节点。这通常使用队列来实现。 在数据结构课程设计中,理解并实现...
在计算机科学中,树是一种非常重要的数据结构,用于表示数据之间的层次关系。树的遍历是研究树结构的关键部分,因为它...这些算法展示了递归在解决树形结构问题中的强大能力,同时强调了理解和熟练掌握树遍历的重要性。
除了递归,还可以用栈来实现非递归的遍历方式。例如,中序遍历的迭代实现: ```cpp void inorderTraversalIterative(Node* root) { stack*> s; Node* curr = root; while (curr != nullptr || !s.empty()) ...
这种遍历方式适用于构建表达式树、打印树的结构或者复制一棵树等场景。 对于二叉树的前序遍历,我们通常采用递归的方式实现。以下是使用JAVA实现的前序遍历代码示例: ```java public class TreeNode { int val; ...
- 输入特定的字符序列可以构建一棵二叉树,然后通过四种遍历方式验证程序的正确性。 总结,这个课程设计旨在让学生理解并实现二叉树的遍历算法,这对于理解和解决实际问题中的数据结构操作至关重要。通过这样的...
根据遍历顺序的不同,主要有前序遍历、中序遍历和后序遍历三种方式: 1. 前序遍历:先访问根节点,再遍历左子树,最后遍历右子树。 2. 中序遍历:对于二叉树,常用于排序,先遍历左子树,再访问根节点,最后遍历右...
常见的三种遍历方式是前序遍历(先根遍历)、中序遍历和后序遍历。对于二叉树,这些遍历方式定义如下: 1. 先根遍历(前序遍历):首先访问根节点,然后遍历左子树,最后遍历右子树。 2. 后根遍历:首先遍历左子树...
根据给定的文件信息,我们可以总结出以下关于“数据结构树的遍历代码”的相关知识点: ### 一、概述 本篇文章将详细解读一个用C语言实现的数据结构——二叉树(Binary Tree)的前序遍历算法。二叉树是一种非线性的...
树遍历是指按照特定顺序访问树的所有节点。通常,有三种主要的遍历方法:前序遍历、中序遍历和后序遍历。 1. **前序遍历**:首先访问根节点,然后遍历左子树,最后遍历右子树。递归实现可以概括为:访问根节点 -> ...
2. **插入单词**:将单词插入到字典树中,使用深度优先遍历的方式逐字符地添加节点。如果某个字符不存在于当前节点的子节点中,就创建一个新的节点并添加到子节点映射中。 ```java void insert(String word, ...
在计算机科学中,树是一种非常重要的数据结构,它模拟了现实世界中的层级关系。C语言是一种底层编程语言,常用于...通过深入研究和实践这些代码,可以提升对树遍历及相关计算的理解,并有助于在实际项目中灵活运用。
这种遍历方式对于二叉搜索树特别有用,因为结果是按值排序的。 - **后序遍历(Postorder Traversal)**:先访问左子树,然后访问右子树,最后访问根节点。 **示例代码**:以下是不使用递归实现二叉树中序遍历的示例...
在给定的压缩包文件中,文件名列表包括"**WUQIN1.C**"、"**WUQIN.C**"、"**LUQI.C**"以及"**www.pudn.com.txt**",这些可能是实现树遍历或图搜索算法的C语言源代码。WUQIN和LUQI可能代表不同的遍历方法,而...
这种遍历方式对于理解哈夫曼树的结构非常有帮助。 在提供的代码中,`postorder()` 函数实现了哈夫曼树的后序遍历。遍历过程中,先递归地遍历左子树,接着遍历右子树,最后访问根节点。这种方式能够确保从底层向上层...