一:图的搜索
是指从一个指定顶点可以到达哪些顶点
二:搜索的分类
1.深度优先 DFS
2.广度优先 BFS
三:深度优先搜索规则
1.如果可能,访问一个邻接的未访问的顶点,标记它,并把它放进栈中
2.当不能执行规则1的时候,如果栈不能为空,就从栈中弹出一个顶点
3.当不能执行规则1和规则2的时候,就完成了整个搜索过程
四:深度优先代码实现
1.创建栈
public class Stack {
//栈的底层实现是数组
long[] arr ;
//表示栈顶索引
int top;
//构造方法
public Stack(){
arr = new long[10];
top = -1; //初始化栈顶没有数据
}
public Stack(int length){
arr = new long[length];
top = -1;
}
//添加数据--压栈
public void push(long value){
arr[++top] = value;
}
//删除数据--弹栈
public long pop(){
return arr[top--]; //弹栈后数组长度减少
}
//查看数据
public long peek(){
return arr[top]; //查看数据,不会弹出数据
}
//判断是否为空
public boolean isEmpty(){
return top==-1; //返回true则为空
}
//判断是否满了
public boolean isFull(){
return top==arr.length-1; //top和数组长度减1 是否相等
}
}
2.创建顶点
//顶点类
public class Vertex {
//顶点名称
public char label;
//添加是否被访问属性
public boolean wasVisited;
public Vertex( char label){
this.label = label;
}
}
3.创建图
//图
public class Graph {
//顶点数组
private Vertex[] vertexList;
//邻接矩阵,二维数组
private int[][] arr;
//顶点最大数量
private int maxSize = 20;
//已添加顶点数量
private int vt;
//引入已创建的建栈,用于存储搜索的数据
private Stack stack;
public Graph(){
//初始化顶点数组
vertexList = new Vertex[maxSize];
//初始化邻接矩阵
arr = new int[maxSize][maxSize];
//初始化值
for (int i= 0;i<maxSize;i++){
for (int j= 0;j<maxSize;j++){
//代表所有的边都不相连
arr[i][j] = 0;
}
}
vt = 0;
//初始化栈
stack = new Stack();
}
//添加顶点
public void addVertex(char label){
//往顶点数组内添加顶点
vertexList[vt++] = new Vertex(label);
}
//添加边
public void addEdge(int start , int end){
//从 start 到 end 连通
arr[start][end] = 1;
//从 end 到 start 自然也连通
arr[end][start] = 1;
}
//查找节点
//参数 v : 代表从哪个节点开始找(前提是这个节点未被访问过)
public int getVertex(int v){
//在邻接矩阵里面找未被访问过的节点
for (int i = 0; i < vt; i++){
//判断节点之间是否相邻 同时 是否未被访问
if (arr[v][i] == 1 && vertexList[i].wasVisited == false){
//当该v和i节点相邻且i节点未被访问过,则返回
return i;
}
}
return -1;
}
//深度优先搜索
public void dfs(){
//首先访问 0 号顶点
vertexList[0].wasVisited = true;
//显示被访问的顶点
displayVertex(0);
//进栈,调用压栈方法
stack.push(0);
//循环访问顶点,当栈不为空的时候才访问,因为栈为空的时候代表访问完成了
while (!stack.isEmpty()){
//获得一个未访问的邻接点
int v = getVertex((int)stack.peek());
//找不到的情况
if (v == -1){
//弹出顶点
stack.pop();
}else{
//找得到则标记再顶点压栈
vertexList[v].wasVisited = true;
//显示
displayVertex(v);
stack.push(v);
}
}
//搜索完成后,复原
for (int i = 0; i < vt ; i++){
vertexList[i].wasVisited = false;
}
}
//显示
public void displayVertex(int v){
System.out.println(vertexList[v].label);
}
}
4.测试
public class Test {
public static void main(String[] args) {
//添加顶点
Graph graph = new Graph();
graph.addVertex('A');
graph.addVertex('B');
graph.addVertex('C');
graph.addVertex('D');
graph.addVertex('E');
//添加边
graph.addEdge(0,1);
graph.addEdge(1,2);
graph.addEdge(0,3);
graph.addEdge(3,4);
//深度优先搜索
graph.dfs(); //A B C D E
}
}