对树形结构数据进行广度优先/深度优先遍历
2016-03-24 15:00
645 查看
今日被问到如何对一个普通的树形结构数据进行遍历,并且分别用广度优先,深度优先遍历,想了一会,深度优先是非常简单的,使用递归几行代码就搞定,但是广度优先呢,想了一会没说出来,回来用eclipse写了一会,终于出来了
public class Node {
String value;
List<Node> children = new ArrayList<Node>();
public Node(String value){
this.value = value;
}
public static void main(String[] args) {
Node root = new Node("A");
root.children.add(new Node("B"));
root.children.add(new Node("C"));
root.children.get(1).children.add(new Node("C1"));
root.children.get(1).children.get(0).children.add(new Node("C11"));
root.children.get(1).children.get(0).children.add(new Node("C12"));
root.children.get(1).children.add(new Node("C2"));
root.children.add(new Node("D"));
root.children.get(2).children.add(new Node("D1"));
root.children.get(2).children.add(new Node("D2"));
// 上面是初始化数据,结构是这样的:
/**
* A
* B
* C
* C1
* C11
* C12
* C2
* D
* D1
* D2
*/
System.out.println("深度优先");
print(root);
System.out.println("-----------------------");
System.out.println("广度优先");
print2(root, root, 1);
}
/**
* 深度优先
*
* @param node
* @param level
*/
static void print(Node node) {
System.out.println(node.value);
if (!node.children.isEmpty()) {
for (Node x : node.children) {
print(x);
}
}
}
/**
* 广度优先
*
* @param root
* @param node
* @param level
*/
static void print2(Node root, Node node, int level) {
if (root == node) {
System.out.println(node.value);
}
print3(root, 1, level);
if (!node.children.isEmpty()) {
for (Node x : node.children) {
print2(root, x, level += 1);
}
}
}
static void print3(Node node, int start, int level) {
List<Node> children = node.children;
if (!children.isEmpty()) {
if (start < level) {
for (Node x : children) {
print3(x, start + 1, level);
}
} else {
for (Node x : children) {
System.out.println(x.value);
}
}
}
}
}
输出结果如下:
深度优先
A
B
C
C1
C11
C12
C2
D
D1
D2
-----------------------
广度优先
A
B
C
D
C1
C2
D1
D2
C11
C12
广度优先感觉实现是实现了,但是效率比较低,每次为了输出第N层,N层前面的每一层都经过了遍历,不知是否还有更好的办法?
今天折腾了一会,写了一个感觉更好[b]的广度优先实现:[/b]
把上面main()中的print2(xxx)换成print5(root);
/**
* 广度优先 —— 法2
*
* @param node
*/
static void print5(Node node) {
List<Node> list = node.children;
do {
for (Node x : list) {
System.out.println(x.value);
}
list = getNextLevelNode(list);
} while (list != null);
}
static List<Node> getNextLevelNode(List<Node> nodeList) {
if (!nodeList.isEmpty()) {
List<Node> list = new ArrayList<Node>();
for (Node node : nodeList) {
list.addAll(node.children);
}
return list;
}
return null;
}
输出结果一样:
-----------------------
广度优先
B
C
D
C1
C2
D1
D2
C11
C12
public class Node {
String value;
List<Node> children = new ArrayList<Node>();
public Node(String value){
this.value = value;
}
public static void main(String[] args) {
Node root = new Node("A");
root.children.add(new Node("B"));
root.children.add(new Node("C"));
root.children.get(1).children.add(new Node("C1"));
root.children.get(1).children.get(0).children.add(new Node("C11"));
root.children.get(1).children.get(0).children.add(new Node("C12"));
root.children.get(1).children.add(new Node("C2"));
root.children.add(new Node("D"));
root.children.get(2).children.add(new Node("D1"));
root.children.get(2).children.add(new Node("D2"));
// 上面是初始化数据,结构是这样的:
/**
* A
* B
* C
* C1
* C11
* C12
* C2
* D
* D1
* D2
*/
System.out.println("深度优先");
print(root);
System.out.println("-----------------------");
System.out.println("广度优先");
print2(root, root, 1);
}
/**
* 深度优先
*
* @param node
* @param level
*/
static void print(Node node) {
System.out.println(node.value);
if (!node.children.isEmpty()) {
for (Node x : node.children) {
print(x);
}
}
}
/**
* 广度优先
*
* @param root
* @param node
* @param level
*/
static void print2(Node root, Node node, int level) {
if (root == node) {
System.out.println(node.value);
}
print3(root, 1, level);
if (!node.children.isEmpty()) {
for (Node x : node.children) {
print2(root, x, level += 1);
}
}
}
static void print3(Node node, int start, int level) {
List<Node> children = node.children;
if (!children.isEmpty()) {
if (start < level) {
for (Node x : children) {
print3(x, start + 1, level);
}
} else {
for (Node x : children) {
System.out.println(x.value);
}
}
}
}
}
输出结果如下:
深度优先
A
B
C
C1
C11
C12
C2
D
D1
D2
-----------------------
广度优先
A
B
C
D
C1
C2
D1
D2
C11
C12
广度优先感觉实现是实现了,但是效率比较低,每次为了输出第N层,N层前面的每一层都经过了遍历,不知是否还有更好的办法?
今天折腾了一会,写了一个感觉更好[b]的广度优先实现:[/b]
把上面main()中的print2(xxx)换成print5(root);
/**
* 广度优先 —— 法2
*
* @param node
*/
static void print5(Node node) {
List<Node> list = node.children;
do {
for (Node x : list) {
System.out.println(x.value);
}
list = getNextLevelNode(list);
} while (list != null);
}
static List<Node> getNextLevelNode(List<Node> nodeList) {
if (!nodeList.isEmpty()) {
List<Node> list = new ArrayList<Node>();
for (Node node : nodeList) {
list.addAll(node.children);
}
return list;
}
return null;
}
输出结果一样:
-----------------------
广度优先
B
C
D
C1
C2
D1
D2
C11
C12
相关文章推荐
- 实验一
- 轻谈“结对编程”
- I.MX6 android shutdown 内核崩溃
- 平台从网页登陆需要写入的注册表项
- Android App开发中将View或Drawable转为Bitmap的方法
- 函数返回值问题
- VMware Horizon 7新功能--即时克隆探索
- Attribute 和 Parameter 的区别
- rlwrap安装
- android 在代码中实现ProgressBar样式自定义
- android --多线程下载
- Deep learning with Theano 官方中文教程(翻译)(四)—— 卷积神经网络(CNN)
- IOC理解
- configure: error: You need a C++ compiler for C++ support.[系统缺少c++环境]
- ElasticSearch 2 (32) - 信息聚合系列之范围限定
- android webview 加载带视频的URL
- 浅析mysql交互式连接&非交互式连接
- Rails教程
- Android图片压缩(质量压缩和尺寸压缩)
- Multiple annotations found at this line: