1.图的构建
以下图为例:
public class Test {
// 顶点信息
class Vertex {
private char label;
private boolean isUsed;
public Vertex(char label) {
this.label = label;
this.isUsed = false;
}
}
// 顶点总数
private final int MAX_VERTS = 20;
// 存储顶点的数组
private Vertex vertexList[];
// 用邻接矩阵来存储各边的关系
private int adjMat[][];
// 顶点个数
private int nVerts;
public Test() {
vertexList = new Vertex[MAX_VERTS];
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int i = 0; i < MAX_VERTS; i++) {
for (int j = 0; j < MAX_VERTS; j++) {
adjMat[i][j] = 0;
}
}
}
/** 创建顶点*/
public void addVertex (char label) {
vertexList[nVerts++] = new Vertex(label);
}
/** 创建边 */
public void addEdge (int start, int end) {
adjMat[start][end] = 1;
adjMat[end][start] = 1;
}
/** 打印顶点信息 */
public void displayVertex (int index) {
System.out.print(vertexList[index].label);
}
public static void main(String[] args) {
Test test = new Test();
test.addVertex('Q'); // 0
test.addVertex('M'); // 1
test.addVertex('N'); // 2
test.addVertex('P'); // 3
test.addVertex('R'); // 4
test.addVertex('O'); // 5
test.addEdge(0,1); // QM
test.addEdge(0,2); // QN
test.addEdge(0,3); // QP
test.addEdge(1,4); // MR
test.addEdge(2,5); // NO
test.addEdge(3,5); // PO
}
}
2.深度优先搜索(Depth First Search, DFS)--- 栈实现
栈实现:
public class Stack {
// 栈中的元素总数
private final int MAX_SIZE = 20;
// 栈信息
private int stackList[];
private int top;
public Stack() {
stackList = new int[MAX_SIZE];
top = -1;
}
/** 入栈 */
public void push(int index) {
stackList[++top] = index;
}
/** 出栈 */
public int pop(){
return stackList[top--];
}
/** 获取当前栈顶信息 */
public int peek(){
return stackList[top];
}
/** 判断栈是否为空 */
public boolean isEmpty() {
return top == -1;
}
}
深度优先遍历算法的实现:
public class Test {
// 顶点信息
class Vertex {
private char label;
private boolean isUsed;
public Vertex(char label) {
this.label = label;
this.isUsed = false;
}
}
// 顶点总数
private final int MAX_VERTS = 20;
// 存储顶点的数组
private Vertex vertexList[];
// 用邻接矩阵来存储各边的关系
private int adjMat[][];
// 顶点个数
private int nVerts;
// 深度遍历算法的实现
private Stack stack;
public Test() {
vertexList = new Vertex[MAX_VERTS];
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int i = 0; i < MAX_VERTS; i++) {
for (int j = 0; j < MAX_VERTS; j++) {
adjMat[i][j] = 0;
}
}
stack = new Stack();
}
/** 创建顶点*/
public void addVertex (char label) {
vertexList[nVerts++] = new Vertex(label);
}
/** 创建边 */
public void addEdge (int start, int end) {
adjMat[start][end] = 1;
adjMat[end][start] = 1;
}
/** 打印顶点信息 */
public void displayVertex (int index) {
System.out.print(vertexList[index].label);
}
/** 找到与某一顶点邻接且未被访问的顶点(栈) */
public int getAdjUnvisitedVertexInStack(int v) {
for(int i = 0; i < nVerts; i++) {
//v顶点与i顶点相邻(邻接矩阵值为1)且未被访问 isUsed==false
if(adjMat[v][i] == 1 && !vertexList[i].isUsed) {
return i;
}
}
return -1;
}
public void depthFirstSearch() {
//从第一个顶点开始访问
vertexList[0].isUsed = true;
displayVertex(0);
stack.push(0);
while(!stack.isEmpty()) {
//找到栈当前顶点邻接且未被访问的顶点
int v = getAdjUnvisitedVertexInStack(stack.peek());
if(v == -1) { //如果当前顶点值为-1,则表示没有邻接且未被访问顶点,那么出栈顶点
stack.pop();
}else { //否则访问下一个邻接顶点
vertexList[v].isUsed = true;
displayVertex(v);
stack.push(v);
}
}
//栈访问完毕,重置所有标记位wasVisited=false
for(int i = 0; i < nVerts; i++) {
vertexList[i].isUsed = false;
}
}
public static void main(String[] args) {
Test test = new Test();
test.addVertex('Q'); // 0
test.addVertex('M'); // 1
test.addVertex('N'); // 2
test.addVertex('P'); // 3
test.addVertex('R'); // 4
test.addVertex('O'); // 5
test.addEdge(0,1); // QM
test.addEdge(0,2); // QN
test.addEdge(0,3); // QP
test.addEdge(1,4); // MR
test.addEdge(2,5); // NO
test.addEdge(3,5); // PO
test.depthFirstSearch(); // 打印结果为:QMRNOP
}
}
3.广度优先搜索(Breadth First Search, BFS)--- 队列实现
队列实现:
public class Queue {
// 队列中的元素总数
private final int MAX_SIZE = 20;
// 队列信息
private int queueList[];
private int front;
private int rear;
public Queue() {
queueList = new int[MAX_SIZE];
front = 0;
rear = -1;
}
/** 插入 */
public void insert(int index) {
if (rear == MAX_SIZE) {
rear = -1;
}
queueList[++rear] = index;
}
/** 删除队首元素 */
public int remove() {
int temp = queueList[front++];
if (front == MAX_SIZE) {
front = 0;
}
return temp;
}
/** 判断队列是否为空 */
public boolean isEmpty() {
return rear + 1 == front || front + MAX_SIZE - 1 == rear;
}
}
广度优先遍历算法的实现:
public class Test {
// 顶点信息
class Vertex {
private char label;
private boolean isUsed;
public Vertex(char label) {
this.label = label;
this.isUsed = false;
}
}
// 顶点总数
private final int MAX_VERTS = 20;
// 存储顶点的数组
private Vertex vertexList[];
// 用邻接矩阵来存储各边的关系
private int adjMat[][];
// 顶点个数
private int nVerts;
// 宽度遍历算法的实现
private Queue queue;
public Test() {
vertexList = new Vertex[MAX_VERTS];
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int i = 0; i < MAX_VERTS; i++) {
for (int j = 0; j < MAX_VERTS; j++) {
adjMat[i][j] = 0;
}
}
queue = new Queue();
}
/** 创建顶点*/
public void addVertex (char label) {
vertexList[nVerts++] = new Vertex(label);
}
/** 创建边 */
public void addEdge (int start, int end) {
adjMat[start][end] = 1;
adjMat[end][start] = 1;
}
/** 打印顶点信息 */
public void displayVertex (int index) {
System.out.print(vertexList[index].label);
}
/** 找到与某一顶点邻接且未被访问的顶点(队列) */
public List<Integer> getAdjUnvisitedVertexInQueue(int v) {
List<Integer> list = new ArrayList<>();
for(int i = 0; i < nVerts; i++) {
//v顶点与i顶点相邻(邻接矩阵值为1)且未被访问 isUsed==false
if(adjMat[v][i] == 1 && !vertexList[i].isUsed) {
list.add(Integer.valueOf(i));
}
}
return list;
}
/** 宽度优先遍历 */
public void breadthFirstSearch() {
vertexList[0].isUsed = true;
displayVertex(0);
queue.insert(0);
while(!queue.isEmpty()) {
// 获取队首元素
int v1 = queue.remove();
List<Integer> result = getAdjUnvisitedVertexInQueue(v1);
if (result.size() > 0) {
result.forEach(item -> {
vertexList[item].isUsed = true;
displayVertex(item);
queue.insert(item);
});
}
}
//搜索完毕,初始化,以便于下次搜索
for(int i = 0; i < nVerts; i++) {
vertexList[i].isUsed = false;
}
}
public static void main(String[] args) {
Test test = new Test();
test.addVertex('Q'); // 0
test.addVertex('M'); // 1
test.addVertex('N'); // 2
test.addVertex('P'); // 3
test.addVertex('R'); // 4
test.addVertex('O'); // 5
test.addEdge(0,1); // QM
test.addEdge(0,2); // QN
test.addEdge(0,3); // QP
test.addEdge(1,4); // MR
test.addEdge(2,5); // NO
test.addEdge(3,5); // PO
test.breadthFirstSearch(); // 打印结果:QMNPRO
}
}