連通圖:需要變成最小生成樹,保持最少的邊,將所有的頂點都連通起來。
不必關系最小的路徑和路徑的長度,只關心數量最少的線
初始狀態每個頂點都有到其他頂點的路徑
最小生成樹就是減去不必要路徑,也能保證圖是連通的
搜算法:廣度優先搜索,深度優先搜索
public class StackX { private final int SIZE=20;//圖的頂點數 private int[] st;//棧的數據存放位置(用於存放當前圖的矩陣中的0,1數據) private int top;//控制棧的個數,棧值增加,棧的刪除 public StackX() {//初始化棧(的屬性) st=new int [SIZE]; top=-1; } //添加數據入棧(數組) public void push(int j) { st[++top]=j; } //刪除棧(數組中的數據) public int pop() { return st[top--]; } //獲取棧中的數據 public int peek() { return st[top]; } //判斷棧是否為空(結束棧的彈出) public boolean isEmpty() { return top==-1; } }
//圖的頂點 public class Vertex { public char label;//頂點的標識符 public boolean wasVisited;//頂點有無被訪問的標志 public Vertex(char lab) {//初始化頂點(屬性) label=lab; wasVisited=false; } }
public class Graph { private final int MAX_VERTS=20;//最大頂點數 private Vertex[] vertexList;//頂點數組 private int [][]adjMat;//頂點關系的領接矩陣(鄰接矩陣的每行或者每列的位置跟頂點數組是對應的) private int nVerts;//當前頂點個數 private StackX theStack;//棧,用於遍歷的工具 public Graph() {//初始化圖 vertexList=new Vertex[MAX_VERTS]; //初始化頂點數組 adjMat=new int [MAX_VERTS][MAX_VERTS] ;//初始化鄰接矩陣 for(int j=0;j<MAX_VERTS;j++) for(int i=0;i<MAX_VERTS;i++) adjMat[i][j]=0; nVerts=0;//初始化當前頂點個數 theStack=new StackX();//建立棧對象 } //向頂點數組中添加頂點對象 public void addVertex(char lab) { vertexList[nVerts++]=new Vertex(lab);//建立lab對象,往數組內添加 } //添加邊(向鄰接矩陣中改變數據為1) public void addEdge(int start,int end) { //因為是無向圖所以(i,j)(j,i)都要添加1 adjMat[start][end]=1; adjMat[end][start]=1; } //打印頂點數組,根據獲取的頂點數組的下標值,打印頂點 public void displayVertex(int v) { System.out.print(vertexList[v].label); } //最小生成樹(深度優先方法) public void mst() { vertexList[0].wasVisited=true;//訪問第一個頂點 theStack.push(0);//將第一個頂點的下標放入棧中(遍歷的初始化) while(!theStack.isEmpty()) {//如果棧中有數據(還存在頂點數組的索引),進行下面操作 int currentVertex=theStack.peek(); int v=getAdjUnvisitedVertex(currentVertex);//獲取棧中值的下一個頂點 if(v==-1) //如果沒有下一個鄰接頂點,就彈出(說明棧中存放的是有鄰接頂點的頂點索引) theStack.pop(); else{//如果有下一個鄰接頂點 ,就將該頂點標記為訪問過的 vertexList[v].wasVisited=true; theStack.push(v); displayVertex(currentVertex); displayVertex(v); System.out.print(" "); } } for(int j=0;j<nVerts;j++)//將定點數組中的頂點狀態還原 vertexList[j].wasVisited=false; } //返回當前頂點是否有相鄰的頂點(只找一個),並且是沒有訪問過的.找到了就返回頂點的數組下標,沒找到就返回-1 public int getAdjUnvisitedVertex(int v) {//v為頂點數組下標 for(int j=0;j<nVerts;j++)//遍歷鄰接矩陣的當前行 if(adjMat[v][j]==1&&vertexList[j].wasVisited==false)//鄰接矩陣的每行每列的位置跟頂點數組是對應的 //判斷某頂點跟當前頂點是否有關系,並且沒有訪問過的 return j; return -1; } }
public class Test { public static void main(String[] agrs) { Graph theGraph=new Graph();//創建一個圖 theGraph.addVertex('A');//添加頂點 theGraph.addVertex('B');//添加頂點 theGraph.addVertex('C');//添加頂點 theGraph.addVertex('D');//添加頂點 theGraph.addVertex('E');//添加頂點 theGraph.addVertex('F');//添加頂點 theGraph.addEdge(0, 1);//添加邊 theGraph.addEdge(0, 2);//添加邊 theGraph.addEdge(0, 3);//添加邊 theGraph.addEdge(0, 4);//添加邊 theGraph.addEdge(1, 2);//添加邊 theGraph.addEdge(1, 3);//添加邊 theGraph.addEdge(1, 4);//添加邊 theGraph.addEdge(2, 3);//添加邊 theGraph.addEdge(2, 4);//添加邊 theGraph.addEdge(3, 4);//添加邊 theGraph.mst(); } }