圖(無向連通無權值圖)深度優先生成最小生成樹


連通圖:需要變成最小生成樹,保持最少的邊,將所有的頂點都連通起來。
不必關系最小的路徑和路徑的長度,只關心數量最少的線
初始狀態每個頂點都有到其他頂點的路徑

最小生成樹就是減去不必要路徑,也能保證圖是連通的
搜算法:廣度優先搜索,深度優先搜索

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

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM