package graphi;
import java.util.LinkedList;
import java.util.Queue;
/**
* 采用邻接表的方式存储无向图
*/
public class UnGraphi {
//标识图中的顶点个数
private int points;
//邻接表
private LinkedList<Integer> [] adjacencyList;
public UnGraphi(int points){
this.points = points;
adjacencyList = new LinkedList[this.points];
//初始化数组中每一个槽位上链表
for(int i=0;i<this.points;i++){
adjacencyList[i] = new LinkedList<Integer>();
}
}
/**
* 向图中添加顶点(边)
*/
public void addPoint(int s,int t){
adjacencyList[s].add(t);
adjacencyList[t].add(s);
}
/**
* 广度优先搜索算法实现
* @param s 起始顶点
* @param t 目标顶点
*/
public void bfs(int s,int t){
if(s==t){
//起始顶点就是目标顶点
return;
}
//定义一个boolean数组,用来记录顶点是否被访问
boolean[] visited = new boolean[this.points];
//起始顶点已经被访问
visited[s] = true;
//定义一个队列,存储已经被访问的,但是还有相邻顶点的顶点
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(s);
//定义一个数组来存储我们的s-t线路
int[] prev = new int[this.points];
//初始化为线路为1
for(int i=0;i<prev.length;i++){
prev[i] = -1;
}
//循环访问对列中没有被访问的顶点
while (!queue.isEmpty()) {
//取出访问过的但是有相邻顶点的顶点
Integer p = queue.poll();
//遍历这个顶点的相邻顶点
for (int j=0;j<adjacencyList[p].size();j++){
//取出相邻顶点
Integer p_edge = adjacencyList[p].get(j);
//相邻顶点没有被访问过
if(!visited[p_edge]){
//记录访问路线
prev[p_edge] = p;
//如果该顶点与目标顶点相等,就打印访问路线
if(p_edge == t){
print(prev,s,t);
return;
}
//否则标记P为已经访问过的顶点
visited[p] = true;
//相邻顶点存入队列
queue.add(p_edge);
}
}
}
}
/**
* 打印从s-t线路的方法
*/
public void print(int[] prev,int s,int t){
if(prev[t] != -1 && s!=t){
print(prev,s,prev[t]);
}
System.out.print(t+">>");
}
//标记我们是否找到目标顶点
private boolean found = false;
/**
* 深度优先搜索算法
* @param s
* @param t
*/
public void dfs(int s,int t){
if(s==t){
return;
}
//标记元素是否被访问过
boolean [] visited = new boolean[this.points];
visited[s] = true;
//定义一个数组记录我们从原顶点到目标顶点之间的线路
int [] prv = new int[this.points];
for (int i=0;i<prv.length;i++){
prv[i]=-1;
}
//递归调用
returnDFS(s,t,visited,prv);
//打印线路
print(prv,s,t);
}
/**
* 查找顶点point到目标顶点的线路
* @param point 顶点
* @param target 目标顶点
* @param visited 已经被访问过的顶点数组
* @param prev 顶点线路数组
*/
private void returnDFS(int point,int target,boolean [] visited,int [] prev){
if(found){
return;
}
//标记当前顶点已经被访问
visited[point] = true;
//如果当前顶点就是目标顶点
if(point == target){
found = true;
return;
}
//获取与当前顶点相连接的所有顶点
for(int j=0;j<adjacencyList[point].size();j++){
//获取与顶点pouint相连的顶点
Integer p_conect = adjacencyList[point].get(j);
if(!visited[p_conect]){
//记录p_connect之前的顶点是P
prev[p_conect] = point;
//递归
returnDFS(p_conect,target,visited,prev);
}
}
}
public static void main(String[] args) {
UnGraphi unGraphi = new UnGraphi(8);
unGraphi.addPoint(0,1);
unGraphi.addPoint(0,3);
unGraphi.addPoint(1,2);
unGraphi.addPoint(1,4);
unGraphi.addPoint(2,5);
unGraphi.addPoint(3,4);
unGraphi.addPoint(4,5);
unGraphi.addPoint(4,6);
unGraphi.addPoint(6,7);
unGraphi.addPoint(7,5);
// System.out.println(unGraphi);
//unGraphi.bfs(0,6);
unGraphi.dfs(0,6);
}
}