代码实现
package 数据结构练习.图的遍历;
import java.util.Scanner;
/**
* 遍历
*
* @param <T>
*/
class SequenceQueue<T> {
static final int defaultSize = 10;
T[] queueArray;
int front;
int rear;
/**
* 基本操作的成员方法
*
* @param size
*/
public SequenceQueue(int size) { //构造大小为size的空队列
queueArray = (T[]) new Object[size];
front = rear = 0;
}
public SequenceQueue() {
this(defaultSize);
} //构造默认大小的空队列
public void enQueue(T x) {//向循环队列的队尾加入一个元素 x
if ((rear + 1) % queueArray.length == front) //追加空间
{
T[] p = (T[]) new Object[queueArray.length * 2];
int j = 0;
for (int i = this.front; i != this.rear; i = (i + 1) % queueArray.length)
p[j++] = queueArray[i];
queueArray = p;
this.front = 0;
this.rear = j;
}
queueArray[rear] = x;
rear = (rear + 1) % queueArray.length;
}
public T deQueue() { //队列不空,删除循环队列 Q 的队头元素并返回其值,否则返回null
if (this.front == this.rear)
return null; //队列空
T x = queueArray[front];
front = (front + 1) % queueArray.length;
return x;
} // DeQueue
public boolean isEmpty() {
return front == rear;
}
}
/**
* 边的类定义
*
* @param <T>
*/
class Edge<T> {
T v1;
T v2;
public Edge(T v1, T v2) {
this.v1 = v1;
this.v2 = v2;
} //无权图的边
}
/**
* 邻接矩阵表示的带权图类
*
* @param <T>
*/
class AMGraph<T> { //定义泛型类
static final int maxVexNum = 20; //最大顶点数
T[] vexs; //顶点数组
int[][] arcs; //邻接矩阵
int vexNum; //顶点数
int arcNum; //边数
/**
* 无参构造方法
*/
public AMGraph() {
vexs = (T[]) new Object[maxVexNum]; //根据最大顶点数构造顶点数组
arcs = new int[maxVexNum][maxVexNum]; //根据最大顶点数构造边数组
this.vexNum = 0; //实际顶点数为0
this.arcNum = 0; //实际边数为0
for (int i = 0; i < maxVexNum; i++) { //初始化邻接矩阵为∞,对角线上为0
for (int j = 0; j < maxVexNum; j++) {
arcs[i][j] = 0;
}
}
}
/**
* 建立无向图
*
* @param vertex
* @param e
*/
public AMGraph(T[] vertex, Edge[] e) {//根据顶点数组和边数组,建立无向网
vexs = (T[]) new Object[vertex.length * 2]; //分配顶点数组最大空间
arcs = new int[maxVexNum][maxVexNum]; //分配邻接矩阵最大空间
this.vexNum = vertex.length; //实际顶点数
this.arcNum = e.length; //实际边数
for (int i = 0; i < this.vexNum; i++) { //复制顶点至顶点数组
this.vexs[i] = vertex[i];
}
for (int i = 0; i < maxVexNum; i++) { //初始化邻接矩阵为∞,对角线上为0
for (int j = 0; j < maxVexNum; j++) {
arcs[i][j] = 0;
}
}
for (int k = 0; k < this.arcNum; k++) { //设置边
int i = locateVex((T) e[k].v1); //获取第i条边第一个顶点v1的下标
int j = locateVex((T) e[k].v2); //获取第i条边第二个顶点v2的下标
if (i == -1 || j == -1)
throw new IndexOutOfBoundsException("非法边");
this.arcs[i][j] = 1; //邻接矩阵i行j列值1
this.arcs[j][i] = this.arcs[i][j]; //无向图,对称位置赋值
}
}
/**
* locateVex方法
*
* @param v
* @return
*/
public int locateVex(T v) {
for (int i = 0; i < vexNum; i++)
if (vexs[i].equals(v))
return i;
return -1;
}
/**
* 深度优先遍历的构造方法
*/
private boolean[] visited;
public void dFS(int v) {
System.out.print(vexs[v] + " ");
visited[v] = true;
for (int j = 0; j < vexNum; j++) {
if (arcs[v][j] == 1 && visited[j] == false)
dFS(j);
}
}
public void DFSTraverse() {
visited = new boolean[vexNum];
for (int v = 0; v < vexNum; v++) {
visited[v] = false;
}
for (int v = 0; v < vexNum; v++) {
if (visited[v] == false)
dFS(v);
}
}
/**
* 广度优先遍历的构造方法
*/
public void bFS(int v) {
SequenceQueue<Integer> q = new SequenceQueue<Integer>();
System.out.print(this.vexs[v] + " ");
visited[v] = true;
q.enQueue(v); //v入队
while (q.isEmpty() == false) {
int w = q.deQueue(); //删除队首元素
for (int j = 0; j < this.vexNum; j++) {
if (this.arcs[w][j] == 1 && !visited[j])
System.out.print(this.vexs[j] + " ");
visited[j] = true;
q.enQueue(j);
}
}
}
public void BFSTraverse() {
visited = new boolean[vexNum];
for (int v = 0; v < vexNum; v++) {
visited[v] = false;
}
for (int v = 0; v < vexNum; v++) {
if (visited[v] == false)
bFS(v);
}
}
}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("请输入顶点数n:");
int n = sc.nextInt();
System.out.println("请输入边数en:");
int en = sc.nextInt();
String[] vertex = new String[n];
System.out.println("请输入" + n + "个顶点");
for (int i = 0; i < n; i++) {
vertex[i] = sc.next();
}
Edge[] e = new Edge[en];
System.out.println("请输入" + en + "条边");
for (int i = 0; i < en; i++) {
String v1 = sc.next();
String v2 = sc.next();
e[i] = new Edge<String>(v1, v2);
}
AMGraph<String> G = new AMGraph(vertex, e);
System.out.println("深度优先遍历序列为:");
G.DFSTraverse();
System.out.println();
System.out.println("广度优先遍历序列为:");
G.BFSTraverse();
}
}
深度优先搜索
广度优先搜索