图的广度优先搜索
描述:
图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接点的邻接点。如此进行下去,直到所有的结点都访问为止。在该题中,假定所有的结点以“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; } }