美文网首页javaJava 杂谈
深度优先算法与最小生成树

深度优先算法与最小生成树

作者: 勃列日涅夫 | 来源:发表于2018-09-22 14:36 被阅读0次
    • 深度优先搜索(DFS),可以被形象的描述为“打破沙锅问到底”,具体一点就是访问一个顶点之后,我继而访问它的下一个邻接的顶点,如此往复,直到当前顶点一被访问或者它不存在邻接的顶点。
      以下为深度优先算法的规则
    • 规则1、:访问一个邻接的未访问的节点,标记它,并把它放入栈中
    • 规则2、当不能执行规则1是,从栈弹出一个顶点
    • 规则3、如果不能完成规则1 规则2则完成搜索
      对于最小生成树,和深度优先算法相似,具体区别是多一个记录,如下mst方法
    /**
     * 
     */
    package com.xzg.heap;
    
    /**
     * @author hasee
     * @TIME 2017年5月2日
     * 1、图的表示,使用临接表或邻接矩阵
     * 2、深度优先搜索算法,核心:栈。规则1、:访问一个邻接的未访问的节点,标记它,并把它放入栈中
     * 规则2、当不能执行规则1是,从栈弹出一个顶点
     * 规则3、如果不能完成规则1 规则2则完成搜索
     */
    public class DeepSearch {
        //测试
        public static void main(String[] args){
            Graph theGraph = new Graph();
            theGraph.addVertex('A');
            theGraph.addVertex('B');
            theGraph.addVertex('C');
            theGraph.addVertex('D');
            theGraph.addVertex('E');
            theGraph.addEdge(0, 1);//ab
            theGraph.addEdge(1, 2);//BC
            theGraph.addEdge(0, 3);//AD
            theGraph.addEdge(3, 4);//DE
            theGraph.dfs();
        }
        
    }
    /**
     * @author hasee
     * @TIME 2017年5月2日
     * 简单实现栈
     */
    class StackX{
    //初始大小
        private final int SIZE = 20;
        private int[] st;
        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;
    }
    }
    /**
     * @author hasee
     * @TIME 2017年5月2日
     * 作为储存搜索的节点,包括数值和是否访问过的标志位
     */
    class Vertx{
        public char lable;
        public boolean wasVisited;
        public Vertx(char lab){
            this.lable = lab;
            this.wasVisited = false;
        }
    }
    class Graph{
        private final int MAX_VRERTS = 20;
        private Vertx vertxList[];//包含所有的节点信息
        private int adjMat[][];//邻接矩阵
        private int nVert;//当前vertxList的指向下标
        private StackX theaStack;
        //初始化
        public Graph(){
            vertxList = new Vertx[MAX_VRERTS];
            adjMat = new int[MAX_VRERTS][MAX_VRERTS];
            nVert = 0;
            for(int j=0;j<MAX_VRERTS;j++)
                for(int k = 0;k<MAX_VRERTS;k++)
                    adjMat[j][k] = 0;
        theaStack = new StackX();
        }
    /**
     * @param lab
     */
    public void addVertex(char lab){
        vertxList[nVert++] = new Vertx(lab);
    }   
    /**
     * @param start
     * @param end
     * 邻接矩阵,添加执行的
     */
    public void addEdge(int start,int end){
        adjMat[start][end] = 1;
        adjMat[end][start] = 1;
    }
    /**
     * @param v
     * 展示节点数值
     */
    public void display(int v){
        System.out.println(vertxList[v].lable);
    }
    /**
     * 深度优先搜索
     * 1、使用peek方法获取栈顶2、试图找到这个栈顶还未访问的邻接点
     * 3、如果没有找到出栈 4、如果找到则把这个节点push到栈中
     */
    public void dfs(){
        vertxList[0].wasVisited = true;//顶点标记为已读
        display(0);
        //初始一个栈顶为0
        theaStack.push(0);
    //只要不为空,就继续搜索
        while(!theaStack.isEmpty()){
            //theaStack.peek获取当前的顶点
        int v = getAdjUnivisitedVertx(theaStack.peek());
        if(v == -1){
            theaStack.pop();
        }
        else{
            vertxList[v].wasVisited = true;
            display(v);
            theaStack.push(v);
        }
    }//重置标志位
        for(int j=0;j<nVert;j++){
            vertxList[j].wasVisited = false;
        }
    }
    /**
     * 深度优先算法实现最小生成树
     */
    public void mst(){
        vertxList[0].wasVisited = true;
        theaStack.push(0);
        while(! theaStack.isEmpty()){
            int curentVertx = theaStack.peek();
            int v = getAdjUnivisitedVertx(curentVertx);
            //表示已经没有邻接点
            if(v == -1){
                theaStack.pop();
            }else{
                vertxList[v].wasVisited = true;
                theaStack.push(v);
    //这里是最小生成树保存
                display(curentVertx);//起点
                display(v);//终点
            }
                    for(int i=0;i<nVert;i++)
                        vertxList[i].wasVisited = true;
        }
    }
    /**
     * @param v
     * @return
     * 深度优先算法关键是找到邻接且没有被访问过的点。
     */
    public  int getAdjUnivisitedVertx(int v){
        for(int i=0;i<nVert;i++){
            if(adjMat[v][i] == 1 &&vertxList[i].wasVisited == false)
                return i;
        }
        return -1;
    }
    }
    

    相关文章

      网友评论

        本文标题:深度优先算法与最小生成树

        本文链接:https://www.haomeiwen.com/subject/tophsxtx.html