zoukankan      html  css  js  c++  java
  • 图(无向连通无权值图)深度优先生成最小生成树

    连通图:需要变成最小生成树,保持最少的边,将所有的顶点都连通起来。
    不必关系最小的路径和路径的长度,只关心数量最少的线
    初始状态每个顶点都有到其他顶点的路径

    最小生成树就是减去不必要路径,也能保证图是连通的
    搜算法:广度优先搜索,深度优先搜索

    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();
            
        }
    
    }
  • 相关阅读:
    MySql 定时完成备份
    smarty插件
    PHP字符串函数小结
    eclipse搭建maven project的spring4 spring mvc mybatis
    C#数组存入引用类型
    C#数组
    【转】Linus:利用二级指针删除单向链表
    [LeetCode] Reverse Linked List II
    ubuntu配置git
    mint安装Node.js
  • 原文地址:https://www.cnblogs.com/S-Mustard/p/7686752.html
Copyright © 2011-2022 走看看