简单的JAVA多叉树问题实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单的JAVA多叉树问题实现相关的知识,希望对你有一定的参考价值。
请编程实现:
一颗多叉树有M层,每个节点的子节点数不定,现要求打印该多叉树的第N层的全部节点。自定义数据结构。
不写代码说说思路也可以,谢谢!
/*
* Copyright Walker Studio
* All Rights Reserved.
*
* 文件名称: TreeNode.java
* 摘 要:
* 作 者: Walker
* 创建时间: 2013-03-19
*/
package com.walker.commons.data.model;
/**
* 树节点
*
* @author Walker
* @version 1.0.0.0
*/
public class TreeNode
/** 节点Id*/
private String nodeId;
/** 父节点Id*/
private String parentId;
/** 文本内容*/
private String text;
/**
* 构造函数
*
* @param nodeId 节点Id
*/
public TreeNode(String nodeId)
this.nodeId = nodeId;
/**
* 构造函数
*
* @param nodeId 节点Id
* @param parentId 父节点Id
*/
public TreeNode(String nodeId, String parentId)
this.nodeId = nodeId;
this.parentId = parentId;
public String getNodeId()
return nodeId;
public void setNodeId(String nodeId)
this.nodeId = nodeId;
public String getParentId()
return parentId;
public void setParentId(String parentId)
this.parentId = parentId;
public String getText()
return text;
public void setText(String text)
this.text = text;
ManyTreeNode.java
/*
* Copyright Walker Studio
* All Rights Reserved.
*
* 文件名称: ManyTreeNode.java
* 摘 要:
* 作 者: Walker
* 创建时间: 2013-03-19
*/
package com.walker.commons.data.model;
import java.util.ArrayList;
import java.util.List;
/**
* 多叉树节点
*
* @author Walker
* @verion 1.0.0.0
*/
public class ManyTreeNode
/** 树节点*/
private TreeNode data;
/** 子树集合*/
private List<ManyTreeNode> childList;
/**
* 构造函数
*
* @param data 树节点
*/
public ManyTreeNode(TreeNode data)
this.data = data;
this.childList = new ArrayList<ManyTreeNode>();
/**
* 构造函数
*
* @param data 树节点
* @param childList 子树集合
*/
public ManyTreeNode(TreeNode data, List<ManyTreeNode> childList)
this.data = data;
this.childList = childList;
public TreeNode getData()
return data;
public void setData(TreeNode data)
this.data = data;
public List<ManyTreeNode> getChildList()
return childList;
public void setChildList(List<ManyTreeNode> childList)
this.childList = childList;
ManyNodeTree.java
/*
* Copyright Walker Studio
* All Rights Reserved.
*
* 文件名称: ManyNodeTree.java
* 摘 要:
* 作 者: Walker
* 创建时间: 2013-03-19
*/
package com.walker.commons.data.model;
import java.util.ArrayList;
import java.util.List;
/**
* 多叉树生成、遍历工具
*
* @author Walker
* @version 1.0.0.0
*/
public class ManyNodeTree
/** 树根*/
private ManyTreeNode root;
/**
* 构造函数
*/
public ManyNodeTree()
root = new ManyTreeNode(new TreeNode("root"));
/**
* 生成一颗多叉树,根节点为root
*
* @param treeNodes 生成多叉树的节点集合
* @return ManyNodeTree
*/
public ManyNodeTree createTree(List<TreeNode> treeNodes)
if(treeNodes == null || treeNodes.size() < 0)
return null;
ManyNodeTree manyNodeTree = new ManyNodeTree();
//将所有节点添加到多叉树中
for(TreeNode treeNode : treeNodes)
if(treeNode.getParentId().equals("root"))
//向根添加一个节点
manyNodeTree.getRoot().getChildList().add(new ManyTreeNode(treeNode));
else
addChild(manyNodeTree.getRoot(), treeNode);
return manyNodeTree;
/**
* 向指定多叉树节点添加子节点
*
* @param manyTreeNode 多叉树节点
* @param child 节点
*/
public void addChild(ManyTreeNode manyTreeNode, TreeNode child)
for(ManyTreeNode item : manyTreeNode.getChildList())
if(item.getData().getNodeId().equals(child.getParentId()))
//找到对应的父亲
item.getChildList().add(new ManyTreeNode(child));
break;
else
if(item.getChildList() != null && item.getChildList().size() > 0)
addChild(item, child);
/**
* 遍历多叉树
*
* @param manyTreeNode 多叉树节点
* @return
*/
public String iteratorTree(ManyTreeNode manyTreeNode)
StringBuilder buffer = new StringBuilder();
buffer.append("\\n");
if(manyTreeNode != null)
for (ManyTreeNode index : manyTreeNode.getChildList())
buffer.append(index.getData().getNodeId()+ ",");
if (index.getChildList() != null && index.getChildList().size() > 0 )
buffer.append(iteratorTree(index));
buffer.append("\\n");
return buffer.toString();
public ManyTreeNode getRoot()
return root;
public void setRoot(ManyTreeNode root)
this.root = root;
public static void main(String[] args)
List<TreeNode> treeNodes = new ArrayList<TreeNode>();
treeNodes.add(new TreeNode("系统权限管理", "root"));
treeNodes.add(new TreeNode("用户管理", "系统权限管理"));
treeNodes.add(new TreeNode("角色管理", "系统权限管理"));
treeNodes.add(new TreeNode("组管理", "系统权限管理"));
treeNodes.add(new TreeNode("用户菜单管理", "系统权限管理"));
treeNodes.add(new TreeNode("角色菜单管理", "系统权限管理"));
treeNodes.add(new TreeNode("用户权限管理", "系统权限管理"));
treeNodes.add(new TreeNode("站内信", "root"));
treeNodes.add(new TreeNode("写信", "站内信"));
treeNodes.add(new TreeNode("收信", "站内信"));
treeNodes.add(new TreeNode("草稿", "站内信"));
ManyNodeTree tree = new ManyNodeTree();
System.out.println(tree.iteratorTree(tree.createTree(treeNodes).getRoot()));
参考技术A XX?XX?XX?XX?XX?XX?
hui追问
好玩啊?傻X
javascript多叉树的实现
1、创造一个节点 数据是以节点的形式存储的: 1 2 3 4 5 6 7 class Node { constructor(data) { this.data = data; this.parent = null; this.children = []; } } 2、创造树 树用来连接节点,就像真实世界树的主干一样,延伸着很多分支 1 2 3 4 5 class MultiwayTree { constructor() { this._root = null; } } 3、添加一个节点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function add(data, toData, traversal) { let node = new Node(data) // 第一次添加到根节点 // 返回值为this,便于链式添加节点 if (this._root === null) { this._root = node; return this; } let parent = null, callback = function(node) { if (node.data === toData) { parent = node; return true; } }; // 根据遍历方法查找父节点(遍历方法后面会讲到),然后把节点添加到父节点 // 的children数组里 // 查找方法contains后面会讲到 this.contains(callback, traversal); if (parent) { parent.children.push(node); node.parent = parent; return this; } else { throw new Error(‘Cannot add node to a non-existent parent.‘); } } 4、深度优先遍历 深度优先会尽量先从子节点查找,子节点查找完再从兄弟节点查找,适合数据深度比较大的情况,如文件目录 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function traverseDF(callback) { let stack = [], found = false; stack.unshift(this._root); let currentNode = stack.shift(); while(!found && currentNode) { // 根据回调函数返回值决定是否在找到第一个后继续查找 found = callback(currentNode) === true ? true : false; if (!found) { // 每次把子节点置于堆栈最前头,下次查找就会先查找子节点 stack.unshift(...currentNode.children); currentNode = stack.shift(); } } } 5、广度优先遍历 广度优先遍历会优先查找兄弟节点,一层层往下找,适合子项较多情况,如公司岗位级别 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function traverseBF(callback) { let queue = [], found = false; queue.push(this._root); let currentNode = queue.shift(); while(!found && currentNode) { // 根据回调函数返回值决定是否在找到第一个后继续查找 found = callback(currentNode) === true ? true : false; if (!found) { // 每次把子节点置于队列最后,下次查找就会先查找兄弟节点 queue.push(...currentNode.children) currentNode = queue.shift(); } } } 6、包含节点 1 2 3 function contains(callback, traversal) { traversal.call(this, callback); } 回调函数算法可自己根据情况实现,灵活度较高 7、移除节点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // 返回被移除的节点 function remove(data, fromData, traversal) { let parent = null, childToRemove = null, callback = function(node) { if (node.data === fromData) { parent = node; return true; } }; this.contains(callback, traversal); if (parent) { let index = this._findIndex(parent.children, data); if (index < 0) { throw new Error(‘Node to remove does not exist.‘); } else { childToRemove = parent.children.splice(index, 1); } } else { throw new Error(‘Parent does not exist.‘); } return childToRemove; } _findIndex实现: 1 2 3 4 5 6 7 8 9 10 function _findIndex(arr, data) { let index = -1; for (let i = 0, len = arr.length; i < len; i++) { if (arr[i].data === data) { index = i; break; } } return index; } 完整算法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 class Node { constructor(data) { this.data = data; this.parent = null; this.children = []; } } class MultiwayTree { constructor() { this._root = null; } //深度优先遍历 traverseDF(callback) { let stack = [], found = false; stack.unshift(this._root); let currentNode = stack.shift(); while(!found && currentNode) { found = callback(currentNode) === true ? true : false; if (!found) { stack.unshift(...currentNode.children); currentNode = stack.shift(); } } } //广度优先遍历 traverseBF(callback) { let queue = [], found = false; queue.push(this._root); let currentNode = queue.shift(); while(!found && currentNode) { found = callback(currentNode) === true ? true : false; if (!found) { queue.push(...currentNode.children) currentNode = queue.shift(); } } } contains(callback, traversal) { traversal.call(this, callback); } add(data, toData, traversal) { let node = new Node(data) if (this._root === null) { this._root = node; return this; } let parent = null, callback = function(node) { if (node.data === toData) { parent = node; return true; } }; this.contains(callback, traversal); if (parent) { parent.children.push(node); node.parent = parent; return this; } else { throw new Error(‘Cannot add node to a non-existent parent.‘); } } remove(data, fromData, traversal) { let parent = null, childToRemove = null, callback = function(node) { if (node.data === fromData) { parent = node; return true; } }; this.contains(callback, traversal); if (parent) { let index = this._findIndex(parent.children, data); if (index < 0) { throw new Error(‘Node to remove does not exist.‘); } else { childToRemove = parent.children.splice(index, 1); } } else { throw new Error(‘Parent does not exist.‘); } return childToRemove; } _findIndex(arr, data) { let index = -1; for (let i = 0, len = arr.length; i < len; i++) { if (arr[i].data === data) { index = i; break; } } return index; } } 控制台测试代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 var tree = new MultiwayTree(); tree.add(‘a‘) .add(‘b‘, ‘a‘, tree.traverseBF) .add(‘c‘, ‘a‘, tree.traverseBF) .add(‘d‘, ‘a‘, tree.traverseBF) .add(‘e‘, ‘b‘, tree.traverseBF) .add(‘f‘, ‘b‘, tree.traverseBF) .add(‘g‘, ‘c‘, tree.traverseBF) .add(‘h‘, ‘c‘, tree.traverseBF) .add(‘i‘, ‘d‘, tree.traverseBF); console.group(‘traverseDF‘); tree.traverseDF(function(node) { console.log(node.data); }); console.groupEnd(‘traverseDF‘); console.group(‘traverseBF‘); tree.traverseBF(function(node) { console.log(node.data); }); console.groupEnd(‘traverseBF‘); // 深度优先查找 console.group(‘contains1‘); tree.contains(function(node) { console.log(node.data); if (node.data === ‘f‘) { return true; } }, tree.traverseDF); console.groupEnd(‘contains1‘) // 广度优先查找 console.group(‘contains2‘); tree.contains(function(node) { console.log(node.data); if (node.data === ‘f‘) { return true; } }, tree.traverseBF); console.groupEnd(‘contains2‘); tree.remove(‘g‘, ‘c‘, tree.traverseBF);
以上是关于简单的JAVA多叉树问题实现的主要内容,如果未能解决你的问题,请参考以下文章