首页 > 代码库 > 图的应用-搜索的实现

图的应用-搜索的实现

图的应用-搜索的实现

图的搜索主要包括两种1个是深度优先搜索,一个是广度优先搜索。深度优先搜索顾名思义就是一直远离源搜索点,搜索下去,深度优先搜索的机制是有栈来实现的,广度优先搜索算法是由队列来实现的,正因为实现的机制不同,所以搜索的方式也不同。

首先讲解一下深度优先搜索方法,首先找一个起始点,然后做三件事:1:首先访问该顶点,2:然后把该点放入到栈中,以便记住它3:标记该点这样就不会再访问该点了。下面可以访问任何与A相连的顶点,只要还没有访问过它。

规则1:访问一个未访问的顶点,标记它把它加入到栈中。

规则2:当不能执行规则1的时候,如果栈不空,就从栈中弹出一个顶点。

规则3:就是规则1和规则2都不能执行的时候,这个搜索就结束了。

深度优先搜索的关键在于如何找到与某一个顶点邻接没有访问过的点,邻接矩阵是关键,找到指定顶点所在的行,从第一列开始向后寻找值为1的列,列号是邻接顶点的号码,检查这个顶点是否未访问过,如果是这样就直接访问下一个顶点,如果该行没有顶点即等于1且未访问过的,那么与指定点相连接的顶点全部访问过了。

代码:

    //返回没有访问过的顶点    public int getAdjUnvisitedVertex(int v)    {        for(int j = 0;j<=currentVertexs;j++)        {            if(adjMat[v][j] == 1&& vertexs[j].wasVisited == false)            {                return j;            }        }        return -1;    }    

深度优先算法的实现:

public void dfs()    {        //从第0个点开始        vertexs[0].wasVisited=true;        //打印该顶点        displayVertex(0);        myStack.push(0);                while(!myStack.isEmpty())        {            int v = getAdjUnvisitedVertex(myStack.peek());            if(v == -1)            {                myStack.pop();            }else{                //跟第一个点处理相同                vertexs[v].wasVisited = true;                //打印该点                displayVertex(v);                //入栈                myStack.push(v);            }        }        //栈空了就结束        for(int j=0;j<currentVertexs;j++)        {            //所有的顶点标志位置为false结束            vertexs[j].wasVisited = false;        }            }

下面讲解广度优先搜索:

深度优先搜索算法表现尽量的远离起始点,广度则不是,尽量的靠近起始点。首先访问起始点的邻接点,然后再访问较远的区域。

规则1:访问下一个未来访问的邻接点(如果存在)这个顶点必须是当前顶点的邻接点,标记它并且把它插入到队列中。

规则2:如果因为已经没有未访问过的顶点不能执行规则1,那么从队列的头取出一个顶点(如果存在),并且使它成为当前的顶点。

规则3:如果队列为空不能执行规则2,就搜索结束。

代码:

import java.util.LinkedList;import java.util.Queue;import java.util.Stack;public class GuDuGraph {    /**     * 这个类是表示数据结构的图     */    private final int max_vertex = 20;//最大的点的数量        private Vertex[]vertexs ;//顶点的数组        private int adjMat[][];//表示一个邻接矩阵        private int currentVertexs;//当前顶点的实际的数量。        private Queue<Integer>queue;        public GuDuGraph()    {        vertexs = new Vertex[max_vertex];        adjMat = new int [max_vertex][max_vertex];        currentVertexs = 0;//当前的数量0个        //初始化邻接矩阵        for(int i = 0;i<max_vertex;i++)        {            for(int j=0;j<max_vertex;j++)            {                adjMat[i][j] = 0;            }        }                queue = new LinkedList<Integer>();    }        //定义图的操作类    //添加顶点的方法    public void addVertex(char lab)    {        vertexs[currentVertexs++] = new Vertex(lab);    }        //添加边的方法    public void addEdge(int start,int end)    {        adjMat[start][end] = 1;        adjMat[end][start] = 1;    }        //为了输出的效果    public void printGraph()    {        for(int i=0;i<max_vertex;i++)        {            for(int j=0;j<max_vertex;j++)            {                System.out.print(adjMat[i][j]+" ");            }            System.out.println();        }    }        //打印顶点的方法的实现    public void displayVertex(int v)    {        System.out.print(vertexs[v].label);    }        //返回没有访问过的顶点    public int getAdjUnvisitedVertex(int v)    {        for(int j = 0;j<=currentVertexs;j++)        {            if(adjMat[v][j] == 1&& vertexs[j].wasVisited == false)            {                return j;            }        }        return -1;    }        public void bfs()    {        //从第0个点开始        vertexs[0].wasVisited=true;        //打印该顶点        displayVertex(0);        queue.add(0);                while(!queue.isEmpty())        {            int v2 = getAdjUnvisitedVertex(queue.peek());            if(v2 == -1)            {                            queue.poll();            }else{                //跟第一个点处理相同                vertexs[v2].wasVisited = true;                //打印该点                displayVertex(v2);                //入栈                queue.add(v2);            }        }        //栈空了就结束        for(int j=0;j<currentVertexs;j++)        {            //所有的顶点标志位置为false结束            vertexs[j].wasVisited = false;        }            }                                    }

 

图的应用-搜索的实现