浅谈数据结构之图的深度优先和广度优先遍历算法(三)
图的遍历
深度优先遍历
图的深度优先搜索(Depth First Search),和树的前序遍历比较类似,简称DFS
它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。
显然,深度优先搜索是一个递归的过程。
广度优先遍历
广度优先搜索算法(Breadth First Search),又称为”宽度优先搜索”或”横向优先搜索”,简称BFS。
它的思想是:从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。
换句话说,广度优先搜索遍历图的过程是以v为起点,由近至远,依次访问和v有路径相通且路径长度为1,2…的顶点。
邻接矩阵深度优先遍历算法
public class MatrixNDG {
/**
* 图顶点个数
*/
int size;
/**
* 图顶点名称
*/
char[] vertexs;
/**
* 图的关系矩阵
*/
int[][] matrix;
/**
* 构造图
* @param vertexs 图的所有顶点
* @param edges 图的关系数组
*/
public MatrixNDG(char[] vertexs, char[][] edges) {
size = vertexs.length;
matrix = new int[size][size];
this.vertexs = vertexs;
for (char[] c : edges) {
// 根据顶点名称确定对应的矩阵下标
int p1 = getPosition(c[0]);
int p2 = getPosition(c[1]);
// 无向图在对称位置存储
matrix[p1][p2] = 1;
matrix[p2][p1] = 1;
}
}
private int getPosition(char ch) {
for (int i = 0; i < vertexs.length; i++) {
if (vertexs[i] == ch) {
return i;
}
}
return -1;
}
private void print() {
System.out.print(" ");
for (char c : vertexs) {
System.out.print(c + " ");
}
System.out.println();
int k = 0;
for (int[] i : matrix) {
System.out.print(vertexs[k++] + " ");
for (int j : i) {
System.out.print(j + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'};
char[][] edges = new char[][]{{'A', 'C'},
{'A', 'D'},
{'A', 'F'},
{'B', 'C'},
{'C', 'D'},
{'E', 'G'},
{'D', 'G'},
{'I', 'J'},
{'J', 'G'},
{'E', 'H'},
{'H', 'K'}};
MatrixNDG pG = new MatrixNDG(vexs, edges);
pG.print();
pG.DFS();
}
private void DFS() {
boolean[] beTraversed = new boolean[size];
System.out.println(vertexs[0] + " ");
beTraversed[0] = true;
DFS(0, 0, beTraversed);
}
//深度优先递归核心算法
private void DFS (int x, int y, boolean[] beTraversed) {
while (y <= size - 1) {
if (matrix[x][y] != 0 && beTraversed[y] == false) {
System.out.println(vertexs[y] + " ");
beTraversed[y] = true;
DFS(y, 0, beTraversed);
}
y++;
}
}
}
邻接表深度优先遍历算法
public class ListNDG {
/**
* 邻接表节点类, 单链表数据结构
*/
Vertex[] vertesLists;
/**
* 链表大小
*/
int size;
class Vertex {
char ch;
Vertex next;
Vertex (char ch) {
this.ch = ch;
}
void add(char ch) {
Vertex node = this;
while (node.next != null) {
node = node.next;
}
node.next = new Vertex(ch);
}
}
public ListNDG(char[] vertexs, char[][] edges) {
size = vertexs.length;
//确定邻接表大小
this.vertesLists = new Vertex[size];
//设置邻接表每一个信息
for (int i = 0; i < size; i++) {
this.vertesLists[i] = new Vertex(vertexs[i]);
}
//存储信息
for (char[] c : edges) {
int p1 = getPosition(c[0]);
vertesLists[p1].add(c[1]);
int p2 = getPosition(c[1]);
vertesLists[p2].add(c[0]);
}
}
private int getPosition(char c) {
for (int i = 0; i < size; i++) {
if (vertesLists[i].ch == c) {
return i;
}
}
return -1;
}
public void print() {
for (int i = 0; i < size; i++) {
Vertex temp = vertesLists[i];
while (temp != null) {
System.out.print(temp.ch + " ");
temp = temp.next;
}
System.out.println();
}
}
public static void main(String[] args) {
char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'};
char[][] edges = new char[][]{{'A', 'C'},
{'A', 'D'},
{'A', 'F'},
{'B', 'C'},
{'C', 'D'},
{'E', 'G'},
{'D', 'G'},
{'I', 'J'},
{'J', 'G'},
{'E', 'H'},
{'H', 'K'}};
ListNDG pG = new ListNDG(vexs, edges);
pG.print();
pG.DFS();
}
public void DFS() {
boolean[] beTraversed = new boolean[size];
for (int i = 0; i < size; i++) {
if (!beTraversed[i]) {
DFS(beTraversed, vertesLists[i]);
}
}
}
//深度优先遍历核心算法
private void DFS(boolean[] beTraversed, Vertex temp) {
System.out.println(temp.ch + " ");
beTraversed[getPosition(temp.ch)] = true;
while (temp != null) {
if (!beTraversed[getPosition(temp.ch)]) {
DFS(beTraversed, vertesLists[getPosition(temp.ch)]);
}
temp = temp.next;
}
}
}
邻接矩阵广度优先遍历算法
public class MatrixNDG {
/**
* 图顶点个数
*/
int size;
/**
* 图顶点名称
*/
char[] vertexs;
/**
* 图的关系矩阵
*/
int[][] matrix;
/**
* 构造图
* @param vertexs 图的所有顶点
* @param edges 图的关系数组
*/
public MatrixNDG(char[] vertexs, char[][] edges) {
size = vertexs.length;
matrix = new int[size][size];
this.vertexs = vertexs;
for (char[] c : edges) {
// 根据顶点名称确定对应的矩阵下标
int p1 = getPosition(c[0]);
int p2 = getPosition(c[1]);
// 无向图在对称位置存储
matrix[p1][p2] = 1;
matrix[p2][p1] = 1;
}
}
private int getPosition(char ch) {
for (int i = 0; i < vertexs.length; i++) {
if (vertexs[i] == ch) {
return i;
}
}
return -1;
}
private void print() {
System.out.print(" ");
for (char c : vertexs) {
System.out.print(c + " ");
}
System.out.println();
int k = 0;
for (int[] i : matrix) {
System.out.print(vertexs[k++] + " ");
for (int j : i) {
System.out.print(j + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'};
char[][] edges = new char[][]{{'A', 'C'},
{'A', 'D'},
{'A', 'F'},
{'B', 'C'},
{'C', 'D'},
{'E', 'G'},
{'D', 'G'},
{'I', 'J'},
{'J', 'G'},
{'E', 'H'},
{'H', 'K'}};
MatrixNDG pG = new MatrixNDG(vexs, edges);
pG.print();
System.out.println("++++++++++++++++++++++++");
pG.BFS();
}
private void BFS() {
boolean[] beTraversed = new boolean[size];
System.out.println(vertexs[0] + " ");
beTraversed[0] = true;
BFS(0, beTraversed);
}
//广度优先遍历核心算法
private void BFS (int x, boolean[] beTraversed) {
LinkedList<Character> list = new LinkedList<>();
int y = 0;
while (y <= size - 1) {
if (matrix[x][y] != 0 && beTraversed[y] == false) {
System.out.println(vertexs[y] + " ");
beTraversed[y] = true;
list.add(vertexs[y]);
}
y++;
}
while (!list.isEmpty()) {
char ch = list.pop();
int index = this.getPosition(ch);
BFS(index, beTraversed);
}
}
}
邻接表广度优先遍历算法
public class ListNDG {
/**
* 邻接表节点类, 单链表数据结构
*/
Vertex[] vertesLists;
/**
* 链表大小
*/
int size;
class Vertex {
char ch;
Vertex next;
Vertex (char ch) {
this.ch = ch;
}
void add(char ch) {
Vertex node = this;
while (node.next != null) {
node = node.next;
}
node.next = new Vertex(ch);
}
}
public ListNDG(char[] vertexs, char[][] edges) {
size = vertexs.length;
//确定邻接表大小
this.vertesLists = new Vertex[size];
//设置邻接表每一个信息
for (int i = 0; i < size; i++) {
this.vertesLists[i] = new Vertex(vertexs[i]);
}
//存储信息
for (char[] c : edges) {
int p1 = getPosition(c[0]);
vertesLists[p1].add(c[1]);
int p2 = getPosition(c[1]);
vertesLists[p2].add(c[0]);
}
}
private int getPosition(char c) {
for (int i = 0; i < size; i++) {
if (vertesLists[i].ch == c) {
return i;
}
}
return -1;
}
public void print() {
for (int i = 0; i < size; i++) {
Vertex temp = vertesLists[i];
while (temp != null) {
System.out.print(temp.ch + " ");
temp = temp.next;
}
System.out.println();
}
}
public static void main(String[] args) {
char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'};
char[][] edges = new char[][]{{'A', 'C'},
{'A', 'D'},
{'A', 'F'},
{'B', 'C'},
{'C', 'D'},
{'E', 'G'},
{'D', 'G'},
{'I', 'J'},
{'J', 'G'},
{'E', 'H'},
{'H', 'K'}};
ListNDG pG = new ListNDG(vexs, edges);
pG.print();
System.out.println("++++++++++++++++++++++++++");
pG.BFS();
}
private void BFS() {
boolean[] beTraversed = new boolean[size];
System.out.println(vertesLists[0].ch);
beTraversed[0] = true;
BFS(0, beTraversed);
}
private void BFS(int x, boolean[] beTraversed) {
Vertex temp = vertesLists[x];
LinkedList<Vertex> list = new LinkedList<>();
while (temp != null) {
if (!beTraversed[getPosition(temp.ch)]) {
System.out.println(temp.ch);
beTraversed[getPosition(temp.ch)] = true;
list.add(temp);
}
temp = temp.next;
}
while (!list.isEmpty()) {
Vertex vertex = list.pop();
int index = getPosition(vertex.ch);
BFS(index, beTraversed);
}
}
}