图的存储以及广度优先搜索算法和深度优先搜索算法

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);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章