图(无向连通无权图)-深度优先搜索

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 dfs() {
        vertexList[0].wasVisited=true;//访问第一个顶点
        displayVertex(0);//输出第一个顶点
        theStack.push(0);//将第一个顶点的下标放入栈中(遍历的初始化)
        while(!theStack.isEmpty()) {//如果栈中有数据(还存在顶点数组的索引),进行下面操作
            int v=getAdjUnvisitedVertex(theStack.peek());//获取栈中值的下一个顶点
            if(v==-1) //如果没有下一个邻接顶点,就弹出(说明栈中存放的是有邻接顶点的顶点索引)
                theStack.pop();
            else{//如果有下一个邻接顶点 ,就将该顶点标记为访问过的
            vertexList[v].wasVisited=true;
            displayVertex(v);
            theStack.push(v);
            }
                
        }
        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.addEdge(0, 1);//添加边
        theGraph.addEdge(0, 2);//添加边
        theGraph.addEdge(0, 3);//添加边
        theGraph.addEdge(1, 3);//添加边
        theGraph.dfs();
        
    }

}

图:用于对数据间关系进行编码的一种机制
图是一种与树有些相像的数据结构
图的分类:有向图 无向图
非连通图 连通图
带权图 无权图(存在实际数据)
深度优先搜索就是在三个顶点中只考虑下一个邻接顶点,并不是多个。判断栈中的顶点是否有邻接顶点,有的话就标记访问过,并且入栈,没有的话就出栈,如此循环。
(0)第一个顶点,即索引为0的顶点被访问,显示顶点,入栈
(1)(访问顶点,显示顶点,入栈)如果有下一个顶点的话
(2)出栈 如果没有下一个顶点的话
(3)最后都得把数组中的顶点标记改为false;

posted @ 2017-10-18 15:07  S-Mustard  阅读(681)  评论(0编辑  收藏  举报