有两种常用的方法可用来搜索图:即深度优先搜索和广度优先搜索。它们最终都会到达所有连通的顶点。深度优先搜索通过栈来实现,而广度优先搜索通过队列来实现。
深度优先搜索:
下面图中的数字显示了深度优先搜索顶点被访问的顺序。
[img]http://dl.iteye.com/upload/attachment/0072/1533/87959b91-1b51-31ea-8ca7-533f41bd02a7.jpg[/img]
为了实现深度优先搜索,首先选择一个起始顶点并需要遵守三个规则:
(1) 如果可能,访问一个邻接的未访问顶点,标记它,并把它放入栈中。
(2) 当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点。
(3) 如果不能执行规则1和规则2,就完成了整个搜索过程。
广度优先搜索:
在深度优先搜索中,算法表现得好像要尽快地远离起始点似的。相反,在广度优先搜索中,算法好像要尽可能地靠近起始点。它首先访问起始顶点的所有邻接点,然后再访问较远的区域。它是用队列来实现的。
下面图中的数字显示了广度优先搜索顶点被访问的顺序。
[img]http://dl.iteye.com/upload/attachment/0072/1535/0edd2cdc-5bf7-317b-b0fb-3fcfec1cef3d.jpg[/img]
实现广度优先搜索,也要遵守三个规则:
(1) 访问下一个未来访问的邻接点,这个顶点必须是当前顶点的邻接点,标记它,并把它插入到队列中。
(2) 如果因为已经没有未访问顶点而不能执行规则1时,那么从队列头取一个顶点,并使其成为当前顶点。
(3) 如果因为队列为空而不能执行规则2,则搜索结束。
下面是一个练习的简单例子:列磁盘目录(深度优先和广度优先实现)
下载源码:
深度优先搜索:
下面图中的数字显示了深度优先搜索顶点被访问的顺序。
[img]http://dl.iteye.com/upload/attachment/0072/1533/87959b91-1b51-31ea-8ca7-533f41bd02a7.jpg[/img]
为了实现深度优先搜索,首先选择一个起始顶点并需要遵守三个规则:
(1) 如果可能,访问一个邻接的未访问顶点,标记它,并把它放入栈中。
(2) 当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点。
(3) 如果不能执行规则1和规则2,就完成了整个搜索过程。
广度优先搜索:
在深度优先搜索中,算法表现得好像要尽快地远离起始点似的。相反,在广度优先搜索中,算法好像要尽可能地靠近起始点。它首先访问起始顶点的所有邻接点,然后再访问较远的区域。它是用队列来实现的。
下面图中的数字显示了广度优先搜索顶点被访问的顺序。
[img]http://dl.iteye.com/upload/attachment/0072/1535/0edd2cdc-5bf7-317b-b0fb-3fcfec1cef3d.jpg[/img]
实现广度优先搜索,也要遵守三个规则:
(1) 访问下一个未来访问的邻接点,这个顶点必须是当前顶点的邻接点,标记它,并把它插入到队列中。
(2) 如果因为已经没有未访问顶点而不能执行规则1时,那么从队列头取一个顶点,并使其成为当前顶点。
(3) 如果因为队列为空而不能执行规则2,则搜索结束。
下面是一个练习的简单例子:列磁盘目录(深度优先和广度优先实现)
import java.io.File;
import java.io.IOException;
import java.util.Stack;
import java.util.Queue;
import java.util.LinkedList;
public class ListFile{
public static void main(String[] args) throws IOException {
File file = new File("c:/java/guest");
DFS1(file);
System.out.println("--------------------------------");
System.out.println("--------------------------------");
// DFS2(file);
BFS(file);
}
// 文件深度非递归遍历
private static void DFS1(File file) throws IOException {
Stack<File> stack = new Stack<File>();
stack.push(file);
File fileInStack = null;
while (!stack.isEmpty()) {
fileInStack = stack.pop();
System.out.println("dir:" + fileInStack.getCanonicalPath());
File[] files = fileInStack.listFiles();
for (File eachFile : files) {
if (eachFile.isFile()) {
System.out.println("file:" + eachFile.getCanonicalPath());
} else {
stack.push(eachFile);
}
}
}
}
// 文件深度递归遍历
private static void DFS2(File file) throws IOException {
System.out.println("dir:" + file.getCanonicalPath());
File[] files = file.listFiles();
for (File eachFile : files) {
if (eachFile.isFile()) {
System.out.println("file:" + eachFile.getCanonicalPath());
} else {
DFS2(eachFile);
}
}
}
// 文件广度非递归遍历
private static void BFS(File file) throws IOException{
System.out.println(file.getCanonicalPath());
Queue<File> queue = new LinkedList<File>();
queue.offer(file);
File fileInQueue = null;
while (queue.size() > 0) {
fileInQueue = queue.poll();
//System.out.println("dir--:" + fileInQueue.getCanonicalPath());
File[] files =fileInQueue.listFiles();
for (File eachFile : files) {
if (eachFile.isFile()) {
System.out.println("file:" + eachFile.getCanonicalPath());
} else {
System.out.println("dir--:" + eachFile.getCanonicalPath());
queue.offer(eachFile);
}
}
}
}
}
下载源码: