圖的存儲以及廣度優先搜索算法和深度優先搜索算法

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

 

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