记录几种关于二叉树遍历的问题及相应实现,代码仅java实现。
二叉树结构定义为:
public class Node {
char val;
Node left;
Node right;
public Node(){}
public Node(int val) {
this.val = val;
}
}
以如下二叉树为例:
1
/ \
2 3
/ \ /
4 5 6
\ /
7 8
\
9
按层遍历
单行输出
输入为示例二叉树,则输出为: 1 2 3 4 5 6 7 8 9
public static void traversalInLayers(Node root) {
if (root == null) return;
Queue<Node> nodes = new LinkedList<>();
nodes.offer(root);
while (!nodes.isEmpty()) {
Node node = nodes.poll();
System.out.print(node.val + " ");
if (node.left != null)
nodes.offer(node.left);
if (node.right != null)
nodes.offer(node.right);
}
}
分层输出
输入为示例二叉树,则输出为:
1
2 3
4 5 6
7 8
9
递归
public static void traversalInLayers(Node root) {
for (int i = 0; ; i++) {
if (doTraversalInLayers(root, i) == 0)
break;
System.out.println("");
}
}
public static int doTraversalInLayers(Node root, int level) {
if(root == null || level < 0) return 0;
if (level == 0) {
System.out.print(root.val + " ");
return 1;
}
return doTraversalInLayers(root.left, level - 1) +
doTraversalInLayers(root.right, level - 1);
}
非递归
使用双队列
public static void traversalInLayers(Node root) {
if (root == null) return;
Queue<Node> firstQueue = new LinkedList<>();
Queue<Node> secondQueue = new LinkedList<>();
firstQueue.add(root);
while(!firstQueue.isEmpty()) {
// 遍历第一个队列
while (!firstQueue.isEmpty()) {
Node node = firstQueue.poll();
System.out.print(node.val + " ");
if (node.left != null)
secondQueue.add(node.left);
if (node.right != null)
secondQueue.add(node.right);
}
System.out.println("");
// 将第二个队列的结点全部放到第一个队列中
while(!secondQueue.isEmpty()) {
firstQueue.add(secondQueue.poll());
}
}
}
使用一个队列和两个指针。
public static void traversalInLayers(Node root) {
if (root == null) return;
Queue<Node> nodes = new LinkedList<>();
int curNum = 0;// 当前访问的结点号
int enQueueNum = 1; // 进队列的结点个数
int layerLastNum = 1;//每行最后一个结点号
nodes.add(root);
while(curNum < enQueueNum) {
layerLastNum = enQueueNum;
while(curNum < layerLastNum) {
Node node = nodes.poll();
System.out.print(node.val + " ");
if (node.left != null) {
nodes.add(node.left);
enQueueNum++;
}
if (node.right != null) {
nodes.add(node.right);
enQueueNum++;
}
curNum++;
}
System.out.println("");
}
}
先序遍历
递归
public static void preOrderTraversal(Node root) {
if (root == null) return;
System.out.print(root.val + " ");
preOrderTraversal(root.left);
preOrderTraversal(root.right);
}
非递归
public static void preOrderTraversal(Node root) {
if (root == null) return;
Stack<Node> nodes = new Stack<>();
while (root != null || !nodes.isEmpty()) {
while (root != null) {
System.out.print(root.val + " ");
nodes.add(root);
root = root.left;
}
root = nodes.pop();
root = root.right;
}
}
中序遍历
递归
public static void inOrderTraversal(Node root) {
if (root == null) return;
inOrderTraversal(root.left);
System.out.print(root.val + " ");
inOrderTraversal(root.right);
}
非递归
public static void inOrderTraversal(Node root) {
if (root == null) return;
Stack<Node> nodes = new Stack<>();
while (root != null || !nodes.isEmpty()) {
while (root != null) {
nodes.add(root);
root = root.left;
}
root = nodes.pop();
System.out.print(root.val + " ");
root = root.right;
}
}
后序遍历
递归
public static void postOrderTraversal(Node root) {
if (root == null) return;
postOrderTraversal(root.left);
postOrderTraversal(root.right);
System.out.print(root.val + " ");
}
非递归
public static void postOrderTraversal(Node root) {
if (root == null) return;
Stack<Node> nodes = new Stack<>();
Node preNode = null;
while(root != null || !nodes.isEmpty()) {
while(root != null) {
nodes.add(root);
root = root.left;
}
root = nodes.peek();
if (root.right == null || root.right == preNode) {
preNode = nodes.pop();
System.out.print(preNode.val + " ");
root = null;
} else {
root = root.right;
}
}
}
深度优先
public static void depthFirstTraversal(Node root) {
if (root == null) return;
Stack<Node> nodes = new Stack<>();
nodes.push(root);
while (!nodes.isEmpty()) {
Node node = nodes.pop();
System.out.print(node.val + " ");
if (node.right != null)
nodes.push(node.right);
if (node.left != null)
nodes.push(node.left);
}
}
广度优先
见按层遍历实现 。