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

 

posted @ 2018-04-05 10:20  leonard丶zou  阅读(187)  评论(0编辑  收藏  举报