二叉树的遍历可分为两种:深度遍历和广度遍历
深度遍历又分为三种:前序、中序、后序遍历,这三种遍历方式可以用递归或栈来实现
广度遍历:即层序遍历, 可以用队列来实现
1、递归
以如下的二叉树为例,遍历该二叉树。
a.建立节点类
public class TreeNode {
int data;
TreeNode leftChild;
TreeNode rightChild;
TreeNode(int data){
this.data = data;
}
}
b.根据二叉树图建立节点集合
public static void main(String[] args){
TreeNode root = new TreeNode(3);
root.leftChild = new TreeNode(2);
root.rightChild = new TreeNode(5);
root.rightChild.rightChild = new TreeNode(7);
root.leftChild.rightChild = new TreeNode(9);
root.leftChild.rightChild.leftChild = new TreeNode(1);
root.leftChild.rightChild.rightChild = new TreeNode(2);
}
c.遍历二叉树
//前序遍历
public static void preOrder(TreeNode tn){
if(tn==null){
//System.out.println(tn);
return;
}
System.out.print(tn.data+" ");
preOrder(tn.leftChild);
preOrder(tn.rightChild);
}
//中序遍历
public static void inOrder(TreeNode tn){
if(tn==null){
//System.out.println(tn);
return;
}
inOrder(tn.leftChild);
System.out.print(tn.data+" ");
inOrder(tn.rightChild);
}
//后序遍历
public static void postOrder(TreeNode tn){
if(tn==null){
//System.out.println(tn);
return;
}
postOrder(tn.leftChild);
postOrder(tn.rightChild);
System.out.print(tn.data+" ");
}
d.遍历结果
3 2 9 1 8 5 7
2 1 9 8 3 5 7
1 8 9 2 7 5 3
2、栈
与递归不同的是,使用栈来遍历二叉树属于使用中间变量-栈来辅助遍历,步骤a、b与使用递归遍历的相同
c.遍历二叉树
1、前序:入栈就打印输出节点数据,即节点访问的顺序等于遍历顺序(从根节点开始访问,先访问左子树,若左子树不为空则把该左子树对应的 节点x 入栈,继续访问 节点x 的左子树。循环直到左子树为空,假设当前节点为y。则节点y出栈,访问节点y的右子树。继续循环直到栈为空)
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode tn=root;
while(tn!=null||!stack.isEmpty()){
while(tn!=null){
System.out.print(tn.data+" ");
stack.push(tn);
tn = tn.leftChild;
}
tn = stack.pop();
tn = tn.rightChild;
}
2、中序:出栈就打印节点数据,即节点出栈顺序等于遍历顺序(其他的与前序相同)
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode tn=root;
while(tn!=null||!stack.isEmpty()){
while(tn!=null){
stack.push(tn);
tn = tn.leftChild;
}
tn = stack.pop();
System.out.print(tn.data+" ");
tn = tn.rightChild;
}
3、后续:增加一个辅助栈,记录所有节点(与前序不同的地方在于,先遍历右子树,将访问到的所有节点入栈2,栈2的出栈顺序就是遍历顺序)
Stack<TreeNode> stack = new Stack<TreeNode>();
Stack<TreeNode> stack2 = new Stack<TreeNode>();
tn=root;
while(tn!=null||!stack.isEmpty()){
while(tn!=null){
stack.push(tn);
stack2.push(tn);
tn = tn.rightChild;
}
tn = stack.pop();
tn = tn.leftChild;
}
int n = stack2.size();
for (int i = 0; i < n; i++) {
System.out.print(stack2.pop().data+" ");
}
d.结果
3 2 9 1 8 5 7
2 1 9 8 3 5 7
1 8 9 2 7 5 3
3、队列
层序遍历, 可以用队列来实现
//层序遍历
public static void levelOrder(TreeNode tn){
Queue<TreeNode> queue = new LinkedList<TreeNode>();
while(tn!=null){
System.out.print(tn.data+" ");
if(tn.leftChild!=null)
queue.offer(tn.leftChild);
if(tn.rightChild!=null)
queue.offer(tn.rightChild);
if(!queue.isEmpty())
tn = queue.poll();
else
break;
}
}