所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问,对二叉树的遍历就是将非线性结构的二叉树中的节点排列在一个线性序列上的过程。访问结点所做的操作依赖于具体的应用问题。
遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。
直接遍历底层数组,没有什么难度。
有两种遍历方式:
深度遍历的先序遍历、中序遍历、后序遍历这三种遍历方式都是针对根节点(D)而言的。先处理根节点的就是先序遍历,其 次处理根节点的就是中序遍历,最后处理根节点的就是后序遍历。
从根结点出发,逆时针沿着二叉树外缘移动,对每个结点均途径三次,最后回到根结点。
先遍历第一层(根节点),再遍历根节点的两个子节点(第二层)。。。逐层遍历二叉树的所有节点。
为了实现广度优先遍历,可以借助具有“FIFO”特征的队列实现,如下:
(1)建立一个队列(先进先出),把树的根节点压入队列;
(2)从队列中弹出一个节点(第一次弹出的就是根节点),然后把该节点的左、右节点压入队列,如果没有子节点,则说明 已经到达叶子节点;
(3)循环重复执行第(2)步,直到队列为空。当队列为空时,说明所有的叶子节点都已经过了队列,也就完成了遍历。
import java.util.ArrayList;
import java.util.List;
import qiuzhitest.TwoLinkBinTree.Node;
/*
* 这里是利用二叉树的二叉链表存储来举例子,具体的可行性做法可以使用一个Tree接口来实现复用性
* */
public class TreeIterator {
//先序遍历
public static List<Node> preIterator(TwoLinkBinTree tree){
return preIterator(tree.getRoot());
}
private static List<Node> preIterator(Node node){
List<Node> list = new ArrayList<Node>();
//优先遍历根节点(相对于树和子树来说)
list.add(node);
//如果节点的左孩子不为空,则递归遍历左孩子,其遍历顺序在根节点之后
if(node.left!=null){
list.addAll(preIterator(node.left));
}
//如果节点的右孩子不为空,则递归遍历右孩子,其遍历顺序在左孩子之后
if(node.right!=null){
list.addAll(preIterator(node.right));
}
return list;
}
//中序遍历
public static List<Node> inIterator(TwoLinkBinTree tree){
return inIterator(tree.getRoot());
}
private static List<Node> inIterator(Node node){
List<Node> list=new ArrayList<Node>();
//优先递归遍历左孩子节点
if(node.left!=null){
list.addAll(inIterator(node.left));
}
//再来遍历根节点(左孩子节点遍历的尽头就是当前需要遍历的结点)
list.add(node);
//最后递归遍历右孩子节点
if(node.right!=null){
list.addAll(inIterator(node.right));
}
//将遍历结果返回
return list;
}
//后序遍历
public static List<Node> postIterator(TwoLinkBinTree tree){
return postIterator(tree.getRoot());
}
private static List<Node> postIterator(Node node){
List<Node> list = new ArrayList<Node>();
//优先递归遍历左孩子节点
if(node.left!=null){
list.addAll(postIterator(node.left));
}
//再来递归遍历右孩子节点
if(node.right!=null){
list.addAll(postIterator(node.right));
}
//当不存在左右节点后,遍历根节点
list.add(node);
return list;
}
}
public List<TreeNode> breadthFirst(){
//定义一个队列,队列里面存放的元素为节点
Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
//定义一个集合,用来存储遍历的结果
List<TreeNode> list = new ArrayList<TreeNode>();
//第一步将根节点进队列
if(root != null){
//将根元素加入到“队列”
queue.offer(root);
}
//只要队列不为空则循环
while(!queue.isEmpty()){
//将该队列的“队尾”的元素添加到List中
list.add(queue.peek());
//将队列的尾元素出队列
TreeNode p = queue.poll();
//如果左子节点不为null,将它加入到“队列”
if(p.left != null){
queue.offer(p.left);
}
//如果右子节点不为null,将它加入到“队列”
if(p.right != null){
queue.offer(p.right);
}
}
return list;
}
参考文章如下:
上次忘记先把队列的实现写了,所以接下来先把队列的java实现给完成了。加油!
因篇幅问题不能全部显示,请点此查看更多更全内容