第一种方法是编程之美上的。用了一个list作为容器,记录每一行的最后一个元素的位置。
看代码:
package a;
import java.util.ArrayList;
import java.util.List;
public class Test1 {
public static void main(String s[]) {
Node a = new Node();
a.value = 1;
Node b = new Node();
b.value = 2;
Node c = new Node();
c.value = 3;
Node d = new Node();
d.value = 4;
Node e = new Node();
e.value = 5;
Node f = new Node();
f.value = 6;
Node g = new Node();
g.value = 7;
Node h = new Node();
h.value = 8;
a.leftchild = b;
a.rightchild = c;
b.leftchild = d;
b.rightchild = e;
c.rightchild = f;
c.leftchild = null;
d.leftchild = null;
d.rightchild = null;
e.leftchild = g;
e.rightchild = h;
f.leftchild = null;
f.rightchild = null;
g.leftchild = null;
g.rightchild = null;
h.leftchild = null;
h.rightchild = null;
fun(a);
}
public static void fun(Node root) {
List<Node> list = new ArrayList<Node>();
if (root == null) {
return;
}
list.add(root);
int cur = 0;
while (cur < list.size()) {
int last = list.size();
while (cur < last) {
System.out.print(list.get(cur).value);
if (list.get(cur).leftchild != null) {
list.add(list.get(cur).leftchild);// 添加左孩子
}
if (list.get(cur).rightchild != null) {
list.add(list.get(cur).rightchild);// 添加右孩子
}
cur++;
}
System.out.println();// 换行
}
}
}
class Node {
Node leftchild;
Node rightchild;
int value;
}
这个代码清晰易懂。但是对于没有接触过的人来说,不容易想出来。自己的一个思路:
先遍历一次树,统计每一层有多少个节点。
然后根据节点的数目,当到达一个层节点的最后一个的时候输出换行。
看代码:
package a;
import java.util.LinkedList;
import java.util.Queue;
public class Test1 {
public static void main(String s[]) {
Node a = new Node();
a.value = 1;
Node b = new Node();
b.value = 2;
Node c = new Node();
c.value = 3;
Node d = new Node();
d.value = 4;
Node e = new Node();
e.value = 5;
Node f = new Node();
f.value = 6;
Node g = new Node();
g.value = 7;
Node h = new Node();
h.value = 8;
a.leftchild = b;
a.rightchild = c;
b.leftchild = d;
b.rightchild = e;
c.rightchild = f;
c.leftchild = null;
d.leftchild = null;
d.rightchild = null;
e.leftchild = g;
e.rightchild = h;
f.leftchild = null;
f.rightchild = null;
g.leftchild = null;
g.rightchild = null;
h.leftchild = null;
h.rightchild = null;
fun(a);
}
public static void fun(Node root) {
int index = 0;
int count = 0;// 统计二叉树的每一层元素个数
int[] ds = new int[10];//这里代码是不严谨的,应该先求树的深度,然后根据深度来申请数组。
depth(ds, root);
Queue<Node> q = new LinkedList<Node>();
q.add(root);
while (!q.isEmpty()) {
count++;
Node node = q.poll();
if (node.leftchild != null) {
q.add(node.leftchild);
}
if (node.rightchild != null) {
q.add(node.rightchild);
}
System.out.print(node.value);
if (count == ds[index]) {
System.out.println();
index++;
count = 0;
}
}
}
public static void depth(int[] ds, Node root) {
if (root != null) {
ds[root.depth]++;
if (root.leftchild != null) {
root.leftchild.depth = root.depth + 1;
depth(ds, root.leftchild);
}
if (root.rightchild != null) {
root.rightchild.depth = root.depth + 1;
depth(ds, root.rightchild);
}
}
}
}
class Node {
int depth;
Node leftchild;
Node rightchild;
int value;
}
这段代码看起来还是比较清晰的。只不过是要遍历两次树,并且还需要一个树深度的数组作为辅助空间。
不过还比较好的是,这个算法是O(n)的算法。空间复杂度取决于树的高度以及每一层上的结点个数。
-------------------------
今天是2012.10.27
百度面试的时候面到这个题目了。
当时回答的算法就是编程之美上的这种方法。可以说,也是比较简单易懂的。