zoukankan      html  css  js  c++  java
  • DFS

    图的深度优先搜索
    描述:
    图的深度优先搜索类似于树的先根遍历,是树的先根遍历的推广。即从某个结点开始,先访问该结点,然后深度访问该结点的第一棵子树,依次为第二顶子树。如此进行下去,直到所有的结点都访问为止。在该题中,假定所有的结点以“A”至“Z”中的若干字符表示,且要求结点的访问顺序根据“A”至“Z”的字典顺序进行访问。例如有如下图:


    如果要求从H开始进行深度优先搜索,则搜索结果为:H->A->K->U->E.
    输入:
    输入只包含一个测试用例,第一行为一个自然数n,表示顶点的个数,第二行为n个大写字母构成的字符串,表示顶点,接下来是为一个n*n大小的矩阵,表示图的邻接关系。数字为0表示不邻接,否则为相应的边的长度。
    最后一行为一个字符,表示要求进行深度优先搜索的起始顶点。
    输出:
    用一行输出深度优先搜索结果,起始点为给定的顶点,各顶点之间用一个空格隔开。要求同一层顶点的邻接点的访问顺序按“A”至“Z”的字典顺序。
    样例输入:
    5
    HUEAK
    0 0 2 3 0
    0 0 0 7 4
    2 0 0 0 0
    3 7 0 0 1
    0 4 0 1 0
    H
    样例输出:
    H A K U E

    算法提示:首先根据图的邻接矩阵创建邻接表(采用后插法,即每个边结点都插入到最后一个位置),然后结合栈结构完成图的深度优先遍历

    代码如下

    package Graph2;
    /**
    5
    HUEAK
    0 0 2 3 0
    0 0 0 7 4
    2 0 0 0 0
    3 7 0 0 1
    0 4 0 1 0
    H
    @author 邹龄晋
     */
    import java.util.Scanner;
    
    
    
    //DFS用栈实现
    
    public class DFSTest {
        public static void main(String[] args) {
    
            Scanner sc = new Scanner(System.in);
            int z = sc.nextInt();
            String str = sc.next();
            int n =str.length();
            int e;
            Graph zg = new Graph(str);
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    e = sc.nextInt();
                    if(e!=0){
                        EdgeNode p = new EdgeNode(j,e);
                        zg.insertR(i, p);
                    }
                }
            }
            //看效果
    //        System.out.println();
    //        zg.printG();
            String c = sc.nextLine();
            c = sc.nextLine();
            int start = 0;
            for (int i = 0; i < n; i++) {
                if (str.charAt(i) == c.charAt(0)) {
                    start = i;
                    break;
                }
            }
            zg.DFS(start);
        
        }
    
    }
    
    //
    class Graph {
        private int n;
        private HeadNode head[];
    
        public Graph() {
        }
    
        public Graph(String str) {
            this.n = str.length();
            head = new HeadNode[n];
            for (int i = 0; i < n; i++) {
                head[i] = new HeadNode(str.charAt(i));
            }
        }
    
        /**
         * 插入方法有以下三种 
         * 1.头插法 p->sn->s(n-1)->....->s2->s1
         * 2.尾插法p->s1->s2->.....->s(n-1)->sn 
         * 3.字典顺序插法
         */
        //1.头插法
        public void insertH(int i,EdgeNode p){
            p.setNext(head[i].getFirst());
            head[i].setFirst(p);
        }
        //2.尾插法
        public void insertR(int i, EdgeNode p){
            if(head[i].getFirst()==null){
                head[i].setFirst(p);
            }else{
                EdgeNode e = head[i].getFirst();
                while(e.getNext()!=null){
                    e = e.getNext();
                }
                e.setNext(p);
            }
            
        }
        // 3.插入方法要求:按字典顺序插入
        public void insert(int i, EdgeNode p) {
            // 1.第一种情况,若头结点后面为null,直接将边结点插入到后面
            if (head[i].getFirst() == null) {
                head[i].setFirst(p);
                return;
            }
            // 2.第二种情况('B'<'C')前面为新插入的点
            if (head[p.getData()].getCh() < head[head[i].getFirst().getData()]
                    .getCh()) {
                p.setNext(head[i].getFirst());
                head[i].setFirst(p);
                return;
            }
            // 3.第三种情况('D'>'C')
            EdgeNode e = head[i].getFirst();
            while (e.getNext() != null
                    && head[p.getData()].getCh() > head[e.getData()].getCh()) {
                e = e.getNext();
            }
            if (e.getNext() != null)
                p.setNext(e.getNext());
            e.setNext(p);
        }
        // 输出图
        public void printG() {
            for (int i = 0; i < n; i++) {
                System.out.print(head[i].getCh() + "->");
                EdgeNode e = head[i].getFirst();
                for (int j = 0; j < n; j++) {
                    while (e != null) {
                        System.out.print(head[e.getData()].getCh() + ",");
                        e = e.getNext();
                    }
                }
                System.out.println();
            }
        }
        public void DFS(int i){
            boolean b[] = new boolean[n];
            Stack s = new Stack();
            s.push(i);
            b[i] = true;
            while(!s.isEmpty()){
                i = s.pop();
                System.out.print(head[i].getCh()+" ");
                EdgeNode e = head[i].getFirst();
                while(e!=null){
                    if(b[e.getData()]==false){
                        s.push(e.getData());
                        b[e.getData()] = true;
                    }
                    e = e.getNext();
                }
            }
        }
    }
    
    // 头结点
    class HeadNode {
        private char ch;
        private EdgeNode first;
    
        public HeadNode() {
    
        }
    
        public HeadNode(char ch) {
            this.ch = ch;
            first = null;
        }
    
        public char getCh() {
            return ch;
        }
    
        public void setCh(char ch) {
            this.ch = ch;
        }
    
        public EdgeNode getFirst() {
            return first;
        }
    
        public void setFirst(EdgeNode first) {
            this.first = first;
        }
    }
    
    // 边结点
    class EdgeNode {
        private int data;
        private int weight;
        private EdgeNode next;
    
        public EdgeNode() {
        }
    
        public EdgeNode(int data, int weight) {
            this.data = data;
            this.weight = weight;
            next = null;
        }
    
        public int getData() {
            return data;
        }
    
        public void setData(int data) {
            this.data = data;
        }
    
        public int getWeight() {
            return weight;
        }
    
        public void setWeight(int weight) {
            this.weight = weight;
        }
    
        public EdgeNode getNext() {
            return next;
        }
    
        public void setNext(EdgeNode next) {
            this.next = next;
        }
    }
    
    class Stack {
        private int top;
        private int data[];
        
    
        public Stack() {
            data = new int[100];
            top = 0;
        }
    
        public void push(int e) {
            data[top++] = e;
        }
    
        public int pop() {
            return data[--top];
        }
    
        public boolean isEmpty() {
            if (top == 0)
                return true;
            return false;
        }
    
        public int getTop() {
            return top;
        }
    
        public void setTop(int top) {
            this.top = top;
        }
    
        public int[] getData() {
            return data;
        }
    
        public void setData(int[] data) {
            this.data = data;
        }
        
    }
    View Code
  • 相关阅读:
    为jquery添加扩展标准思路
    linux 相关命令
    通过设置PHPSESSID保存到cookie实现免登录
    CentOs7 配置nfs 系统
    ajax 异步 跨域上传图片
    php下载并安装pear脚本
    php基于swoole扩展的WebSocket
    php冒泡排序
    微信公众号验证TOKEN
    CSS清浮动处理(Clear与BFC)
  • 原文地址:https://www.cnblogs.com/zoulingjin/p/8721344.html
Copyright © 2011-2022 走看看