zoukankan      html  css  js  c++  java
  • BFS

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


    如果要求从H开始进行广度优先搜索,则搜索结果为:H->A->E->K->U.
    输入:
    输入只包含一个测试用例,第一行为一个自然数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 E K U

    import java.util.Scanner;
    
    /**
     * 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 邹龄晋 BFS需要借助队列queue的数据结构
     */
    public class BFSTest {
        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.insert(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.BFS(start);
        }
    }
    
    // 构造图
    class Graph {
        private int n;
        private HeadNode head[];
    
        public Graph(String str) {
            n = str.length();
            head = new HeadNode[n];
            for (int i = 0; i < n; i++) {
                head[i] = new HeadNode(str.charAt(i));
            }
        }
    
        // 插入方法要求:按字典顺序插入
        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 BFS(int start) {
            int flag[] = new int[n];
            for (int i = 0; i < n; i++)
                flag[i] = 0;
            MyQueue q = new MyQueue(4);
            q.in(start);
            flag[start] = 1;
            while (!q.isEmpty()) {
                int e = q.out();
                System.out.print(head[e].getCh() + " ");
                // 再把后面没有访问的入队
                EdgeNode p = head[e].getFirst();
                while (p != null) {
                    if (flag[p.getData()] == 0) {
                        q.in(p.getData());
                        flag[p.getData()] = 1;
                    }
                    p = p.getNext();
                }
            }
        }
    
        // 输出图
        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();
            }
        }
    }
    
    // 头结点
    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;
        }
    }
    
    // 利用队列实现BFS
    class MyQueue {
        private int maxsize;
        private int front;
        private int rear;
        private int data[];
    
        public MyQueue() {
        }
    
        public MyQueue(int n) {
            maxsize = n;
            data = new int[n];
            rear = front = 0;
        }
    
        public boolean isFull() {
            if ((rear + 1) % maxsize == front)
                return true;
            return false;
        }
    
        public boolean isEmpty() {
            if (rear == front)
                return true;
            return false;
        }
    
        public void in(int e) {
            if (isFull())
                return;
            data[rear] = e;
            rear = (rear + 1) % maxsize;
        }
    
        public int out() {
            if (isEmpty())
                return -1;
            int e = data[front];
            front = (front + 1) % maxsize;
            return e;
        }
    
        public int getMaxsize() {
            return maxsize;
        }
    
        public void setMaxsize(int maxsize) {
            this.maxsize = maxsize;
        }
    
        public int getFront() {
            return front;
        }
    
        public void setFront(int front) {
            this.front = front;
        }
    
        public int getRear() {
            return rear;
        }
    
        public void setRear(int rear) {
            this.rear = rear;
        }
    
        public int[] getData() {
            return data;
        }
    
        public void setData(int[] data) {
            this.data = data;
        }
    }
    View Code
  • 相关阅读:
    白书上的BellmanFord模板
    c#中的分部类和分部方法
    c#类
    浪潮gs开发平台学习平台快速开发入门
    c#学习积累
    自定义属性编辑器
    hibernate 中的hql,nativesql ,list(),iterate() 的使用规则
    c#继承
    浪潮gs中间件服务器,客户端,数据库sqlserver安装注意事项
    c#接口
  • 原文地址:https://www.cnblogs.com/zoulingjin/p/8721338.html
Copyright © 2011-2022 走看看