(算法入門)基本圖論-深度優先搜索之JAVA實現

DFS與BFS較爲簡單,是圖論的基礎。在以後的實驗中,不管是動態規劃、貪心算法、回溯法都會以DFS或BFS爲基礎,應當是我們每個人都要掌握的。

在這裏分享一個關於DFS的JAVA實現算法。


深度優先搜索的算法描述如下:

從圖中某頂點v出發:

(1)訪問頂點v;

(2)依次從v的未被訪問的鄰接點出發,對圖進行深度優先遍歷;直至圖中和v有路徑相通的頂點都被訪問;

(3)若此時圖中尚有頂點未被訪問,則從一個未被訪問的頂點出發,重新進行深度優先遍歷,直到圖中所有頂點均被訪問過爲止。


具體設計:

1. 數據結構

採用鄰接鏈表作爲圖的數據結構。而我是用的鄰接鏈表法分爲三個類,即圖類Graph,頭節點類VNode,邊類ArcNode。由於這段數據結構涉及到之後會提到的圖類算法,部分屬性在單純的DFS中是不必要的,大家可以根據自己的需求對各個類進行修改。

其具體設計如下:

public class Graph {//圖
	public  VNode[] arrVnode=new VNode[100] ;//頭結點數組
	public int vexmun,arcmun;//節點總數、邊界總數
	public int time;//記錄打開、關閉節點的時間
}

public class VNode {//頭節點類
	public int data;//節點的內容
	public boolean visited=false;//是否訪問過
	public boolean ifclosed=false;//是否被放在關閉的表中
	public int distance=10000;//距離某一點的最短距離
	public int front=10000;//前驅節點
	public ArcNode nextarc=null;//下一條邊
	public int entertime,exittime;//打開、關閉節點的時間
}

public class ArcNode{//邊類
	public int adjvex;//該弧所指向的頂點的位置
	public int weight=0;//該邊的權值
	public ArcNode nextarc=null;//下一條邊
	}

2.圖的初始化


package Graph;
import Queue.*;
//import javax.swing.*;
public class GrahpFunction {
	Graph Graph1=new Graph();
 public Graph CreateGrahp(int vexnum,int arcnum,int[] a,int[] b,int[] c){
	 
	 Graph1.vexmun=vexnum;
	 Graph1.arcmun=arcnum;
	 
	 for(int i=1;i<=Graph1.vexmun;i++){
		 VNode d= new VNode();
		 Graph1.arrVnode[i]=d;
		 Graph1.arrVnode[i].data=i;
		 Graph1.arrVnode[i].nextarc=null;
	 }
	 
	 for(int arc=1;arc<=Graph1.arcmun;arc++){
		 int startint=a[arc];//開始節點
		 int endint=b[arc];//結束節點
		 int weightint=c[arc];//權值
//		 int  weightint=return_position(Integer.parseInt(Weight));
		 if(Graph1.arrVnode[startint].nextarc==null){
			 
		 ArcNode ArcNode_p=new ArcNode();//這是一個邊
		 ArcNode_p.adjvex=endint;
		 ArcNode_p.nextarc=null;
		 ArcNode_p.weight=weightint;
		 Graph1.arrVnode[startint].nextarc=ArcNode_p;
		 }else{
		 ArcNode p=Graph1.arrVnode[startint].nextarc;
		 while(p.nextarc!=null){
			 p=p.nextarc;
		 }
		 ArcNode ArcNode_p=new ArcNode();
		 ArcNode_p.adjvex=endint;
		 ArcNode_p.nextarc=null;
		 ArcNode_p.weight=weightint;
		 p.nextarc=ArcNode_p; 
		 }
	 }
	 
	 for(int i=1;i<=Graph1.vexmun;i++){
		  visited[i]=false;
		  queueed[i]=false;
	  }
	  
	 return Graph1;
 }
 
 public int return_position(int data){
	 for(int j=1;j<=Graph1.vexmun;j++){
		 if(data==Graph1.arrVnode[j].data){
			 return j;
		 }
	 }
	 return 0;
 }
 boolean[] visited=new boolean[100];
 boolean[] queueed=new boolean[100];
}



3.DFS算法

這個算法由兩部分組成,遍歷所有節點的DFS(GraphG),與遞歸調用的DFS_VISIT(G,v)。

在使用的過程中,需要對DFS類進行初始化,從DFS方法開始調用,遍歷所有節點防止有節點沒有訪問到。


public void DFS(Graph G){//DFS的起始調用方法
	int vexmun=G.vexmun;
	G.time=0;
	for(int v=1;v<=vexmun;v++){
		if(G.arrVnode[v].visited==false){
			DFS_VISIT(G,v);
		}
	}
}


public void DFS_VISIT(Graph G,int v){//應用遞歸的DFS訪問
	G.arrVnode[v].visited=true;
	G.time++;//time是給後面的拓撲排序實驗用的
	G.arrVnode[v].entertime=G.time;
	System.out.println(G.arrVnode[v].data);
	ArcNode node=G.arrVnode[v].nextarc;
	while(node!=null){
		int p=node.adjvex;
	  if(G.arrVnode[p].visited==false&&G.arrVnode[p]!=null){
		  DFS_VISIT( G , p);
	            }
	    node=node.nextarc;
	                    }
	G.time++;
	G.arrVnode[v].exittime=G.time;
}

4.主函數

主函數測試的時候,我採用的是文件輸入的方式,用了普林斯頓大學《算法(第四版)》提供的外部函數庫stdlib.jar,而且之後的一些涉及到排序的算法我也是用了其提供的algs4.jar,有需要的同學可以去網上下載一下。

public class Test_DFS {
	
   public  static void main(String[] args){
	   int[] a=new int[10000];
	   int[] b=new int[10000];
	   int[] c=new int[10000];
	   int[] shortest=new int[10000];////////////////
	   In in = new In(args[0]);
	   int vexnum=in.readInt();
	   int arcnum=in.readInt();
	   for(int arc=1;arc<=arcnum;arc++){
		   a[arc]=in.readInt();
		   b[arc]=in.readInt();
		   c[arc]=in.readInt();
	   }
	   for(int arc=1;arc<=arcnum;arc++){
		   shortest[arc]=10000;
	   }
	   GrahpFunction GrahpFuntion=new GrahpFunction();
	   Queue Queue=new Queue();
	   Graph G=GrahpFuntion.CreateGrahp(vexnum,arcnum,a,b,c);
	   Toposort top=new Toposort();
	   top.Toposortmethod(G);
 
System.out.println("DFS結果爲:");
  GrahpFuntion.DFS1(G);



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