实现树的深度优先搜索(DFS)和广度优先搜索(BFS)
1.深度优先遍历(DFS)
深度优先搜索 (depth first search,DFS)是对先序遍历的推广,我们从某个顶点A开始处理A,然后递归遍历所有与A节点邻接的顶点。当访问一个顶点A的时候,由于我们当时已经到了该点处,因此可以标记该点是访问过的,并且对于尚未被标记的所有邻接顶点递归调用DFS进行计算。
简单说:DFS就是先尽可能达到当前遍历路径能够达到最长的路径,一旦达到该路径终点,再回溯,从原来已遍历过顶点处开始新的分支路径的遍历。
深度优先遍历各个节点,需要使用到栈(Stack)这种数据结构。Stack的特点是是先进后出,首先将右节点压入栈中,在将左节点压入栈中,这样出栈顺序就是先左节点再右节点。
整个遍历过程如下:首先将A节点压入栈中,stack(A);
将A节点弹出,同时将A的子节点C,B压入栈中,此时B在栈的顶部,stack(B,C);
将B节点弹出,同时将B的子节点E,D压入栈中,此时D在栈的顶部,stack(D,E,C);
将D节点弹出,由于D没有子节点压入,此时E在栈的顶部,stack(E,C);
将E节点弹出,同时将E的子节点H压入,stack(H,C);
将H节点弹出,由于H没有子节点压入,此时C在栈的顶部,同时将C的G,F子节点压入栈中,stack(C,F,G);
…依次往下,最终遍历完成,遍历结果是:A,B,D,E,H,C,F,I,G。
(1)非递归代码实现如下:
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Main1 {
public ArrayList<Integer> DfsTree(TreeNode root) {
ArrayList<Integer> lists = new ArrayList<I>();
if(root == null)
return lists;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode tree = stack.pop();
//先往栈中压入右节点,再压左节点,出栈就是先左节点后出右节点了(先序遍历推广)。
if(tree.right != null)
stack.push(tree.right);
if(tree.left != null)
stack.push(tree.left);
lists.add(tree.val);
}
return lists;
}
}
(2)递归代码实现DFS如下:
private void DfsRecursive(TreeNode root){
if (root != null)
{
System.out.print(root.value+" ");
DfsRecursive(root.left);
DfsRecursive(root.right);
}
}
2.广度优先遍历(BFS)
广度优先搜索基本操作是和深度优先差不多的,只不过这里是通过队列来实现的,找到一个起点A,并将A相邻的点放入队列中,这时将队首元素B取出,并将B相邻且没有访问过的点放入队列中,不断重复这个操作,直至队列清空,这个时候依次访问的顶点就是遍历的顺序。
广度优先遍历树,需要用到队列(Queue)来存储节点对象,队列的特点就是先进先出。先往队列中插入左节点,再插入右节点,队列出队就是先出左节点,再出右节点。
首先将A节点插入队列中,队列中有元素(A);
将A节点弹出,同时将A节点的左节点B、右节点C依次插入队列,B在队首,C在队尾,(B,C),此时得到A节点;
将队首元素B弹出,并将B的左节点D、右节点E插入队列,C在队首,E在队尾(C,D,E),此时得到B节点;
再将队首元素C弹出,并将C节点的左节点F,右节点G依次插入队列,(D,E,F,G),此时得到C节点;
将D弹出,此时D没有子节点,队列中元素为(E,F,G),得到D节点;
。。。以此类推。最终的遍历结果为:A,B,C,D,E,F,G,H,I。
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Main2{
public ArrayList<Integer> BfsTree(TreeNode root) {
ArrayList<Integer> lists = new ArrayList<>();
if(root == null)
return lists;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode tree = queue.poll();
if(tree.left != null)
queue.offer(tree.left);
if(tree.right != null)
queue.offer(tree.right);
lists.add(tree.val);
}
return lists;
}
}
上一篇: windows10配置pytorch
下一篇: 利用队列实现BFS(广度优先搜索)
推荐阅读
-
PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解
-
python深度优先搜索和广度优先搜索
-
PHP实现二叉树的深度优先与广度优先遍历方法
-
DFS(一):深度优先搜索的基本思想
-
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
-
可能是目前为止最为详细的深度优先搜索DFS和广度优先搜索BFS算法分析
-
数据结构与算法-----BFS与DFS(广度优先搜索与深度优先搜索)
-
数据结构与算法_深度优先搜索(DFS)与广度优先搜索(BFS)详解
-
Java数据结构与算法:图、图的概念、深度优先搜索DFS、广度优先搜索BFS、思路分析、代码实现
-
【数据结构】图的遍历——深度优先搜索DFS、广度优先搜索BFS