版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33127597/article/details/79850172
图的遍历分为深度优先遍历和广度优先遍历
总结下图的遍历:
- 深度优先遍历
就像一棵树的前序遍历
A B C D E F G H
A 1 1
B 1 1 1
C 1 1 1
D 1 1 1
E 1
F 1 1
G 1 1
H 1 1
主要是无向图邻接矩阵,就是递归遍历找到。
1.先创建Node结点,存放数据(data),布尔变量值m_bIsVisted(当前结点是否访问过)
2.遍历前先加入权值。默认为1
贴上遍历代码:
// 深度优先遍历
public void depthFirstTraverse(int nodeIndex) {
int value;
System.out.print(nodeArray[nodeIndex].data + " ");
nodeArray[nodeIndex].m_bIsVisted = true;
for (int i = 0; i < capacity; i++) {
value = getValueFromMatrix(nodeIndex, i);
if (value != 0) {
//访问过了就退出
if (nodeArray[i].m_bIsVisted) {
continue;
}
depthFirstTraverse(i);
}
}
}
- 广度优先遍历
按照树的结构一层一层的往下找
判断上一层结点与其他结点有连接的 就找出来
贴上代码
//广度优先遍历
public void breadthFirstTraverse(int nodeIndex) {
System.out.println();
System.out.print(nodeArray[nodeIndex].data + " ");
nodeArray[nodeIndex].m_bIsVisted = true;
ArrayList list = new ArrayList();
list.add(nodeIndex);
breadthFirstTraverseImpl(list);
}
public void breadthFirstTraverseImpl(ArrayList list) {
int value;
ArrayList curList = new ArrayList();
for (int i = 0; i < list.size(); i++) { //上一层结点
for (int j = 0; j < capacity; j++) { //上一层的结点与其他点是否有连接
value = getValueFromMatrix((Integer) list.get(i), j);
if (value != 0) {
if (nodeArray[j].m_bIsVisted) { //访问过了就退出
continue;
}
System.out.print(nodeArray[j].data + " ");
nodeArray[j].m_bIsVisted = true;
curList.add(j);
}
}
}
if (curList.size() == 0)
return;
else {
breadthFirstTraverseImpl(curList);
}
}
- 贴上全部代码
package graph;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Created by yxf on 2018/4/6.
* <p>
* A
* / \
* B D
* / \ / \
* C F G- H
* \ /
* E
* <p>
* A B C D E F G H
* A 1 1
* B 1 1 1
* C 1 1 1
* D 1 1 1
* E 1
* F 1 1
* G 1 1
* H 1 1
*/
public class Graph<T> {
private final int DEFAULT_SIZE = 8;//设置默认尺寸
private int capacity; //图中最多可容纳的顶点数
private int nodeCount;//已经添加的顶点(结点)个数
private Node[] nodeArray; //用来存放顶点数组
private int[] matrix; //用来存放邻接矩阵
private final int value = 1; //默认权重
public static class Node<T> {
private T data; //数据
private boolean m_bIsVisted = false; //当前结点是否访问
public Node(T data) {
this.data = data;
}
public Node(T data, boolean m_bIsVisted) {
this.data = data;
this.m_bIsVisted = m_bIsVisted;
}
}
public Graph() {
capacity = DEFAULT_SIZE;
nodeArray = new Node[capacity];
matrix = new int[capacity * capacity];
}
public Graph(int capacity) {
this.capacity = capacity;
nodeArray = new Node[capacity];
matrix = new int[this.capacity * this.capacity];
}
//向图中加入顶点(结点)
public boolean addNode(T element) {
if (nodeCount < 0 && nodeCount > capacity)
throw new IndexOutOfBoundsException("数组异常出界..");
Node node = new Node(element);
nodeArray[nodeCount] = node;
nodeCount++;
return true;
}
//重置结点
public void resetNode() {
for (int i = 0; i < nodeCount; i++) {
nodeArray[i].m_bIsVisted = false;
}
}
/**
* 为有向图设置邻接矩阵
*
* @param row
* @param col
* @param val 权值 默认为1
* @return
*/
public boolean setValueToMatrixForDirectedGraph(int row, int col, int val) {
if (row < 0 || row > capacity || col < 0 || col > capacity) {
return false;
}
matrix[row * capacity + col] = val;
return true;
}
public boolean setValueToMatrixForDirectedGraph(int row, int col) {
if (row < 0 || row > capacity || col < 0 || col >= capacity) {
return false;
}
matrix[row * capacity + col] = value;
return true;
}
/**
* 为无向图设置邻接矩阵
*
* @param row
* @param col
* @param val 权值 默认为1
* @return
*/
public boolean setValueToMatrixForUndirectedGraph(int row, int col, int val) {
if (row < 0 || row > capacity || col < 0 || col >= capacity) {
return false;
}
matrix[row * capacity + col] = val;
matrix[col * capacity + row] = val;
return true;
}
public boolean setValueToMatrixForUndirectedGraph(int row, int col) {
if (row < 0 || row > capacity || col < 0 || col >= capacity) {
return false;
}
matrix[row * capacity + col] = value;
matrix[col * capacity + row] = value;
return true;
}
//从矩阵中获取权值
private int getValueFromMatrix(int row, int col) {
if (row < 0 || row > capacity || col < 0 || col >= capacity) {
return -1;
}
return matrix[row * capacity + col];
}
// 深度优先遍历
public void depthFirstTraverse(int nodeIndex) {
int value;
System.out.print(nodeArray[nodeIndex].data + " ");
nodeArray[nodeIndex].m_bIsVisted = true;
for (int i = 0; i < capacity; i++) {
value = getValueFromMatrix(nodeIndex, i);
if (value != 0) {
//访问过了就退出
if (nodeArray[i].m_bIsVisted) {
continue;
}
depthFirstTraverse(i);
}
}
}
//广度优先遍历
public void breadthFirstTraverse(int nodeIndex) {
System.out.println();
System.out.print(nodeArray[nodeIndex].data + " ");
nodeArray[nodeIndex].m_bIsVisted = true;
ArrayList list = new ArrayList();
list.add(nodeIndex);
breadthFirstTraverseImpl(list);
}
public void breadthFirstTraverseImpl(ArrayList list) {
int value;
ArrayList curList = new ArrayList();
for (int i = 0; i < list.size(); i++) { //上一层结点
for (int j = 0; j < capacity; j++) { //上一层的结点与其他点是否有连接
value = getValueFromMatrix((Integer) list.get(i), j);
if (value != 0) {
if (nodeArray[j].m_bIsVisted) { //访问过了就退出
continue;
}
System.out.print(nodeArray[j].data + " ");
nodeArray[j].m_bIsVisted = true;
curList.add(j);
}
}
}
if (curList.size() == 0)
return;
else {
breadthFirstTraverseImpl(curList);
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < capacity; i++) {
for (int j = 0; j < capacity; j++) {
sb.append(matrix[i * capacity + j] + " ");
}
sb.append("\r\n");
}
int len = sb.length();
return sb.delete(len - 2, len).toString();
}
}
- 测试代码
public static void main(String[] args) {
Graph graph = new Graph();
graph.addNode("A");
graph.addNode("B");
graph.addNode("C");
graph.addNode("D");
graph.addNode("E");
graph.addNode("F");
graph.addNode("G");
graph.addNode("H");
graph.setValueToMatrixForUndirectedGraph(0,1);
graph.setValueToMatrixForUndirectedGraph(0,3);
graph.setValueToMatrixForUndirectedGraph(1,2);
graph.setValueToMatrixForUndirectedGraph(1,5);
graph.setValueToMatrixForUndirectedGraph(2,4);
graph.setValueToMatrixForUndirectedGraph(2,5);
graph.setValueToMatrixForUndirectedGraph(3,6);
graph.setValueToMatrixForUndirectedGraph(3,7);
graph.setValueToMatrixForUndirectedGraph(6,7);
System.out.println(graph);
graph.resetNode();
System.out.println("深度优先遍历:");
graph.depthFirstTraverse(0);
graph.resetNode();
System.out.println();
System.out.println("广度优先遍历:");
graph.breadthFirstTraverse(0);
}
0 1 0 1 0 0 0 0
1 0 1 0 0 1 0 0
0 1 0 0 1 1 0 0
1 0 0 0 0 0 1 1
0 0 1 0 0 0 0 0
0 1 1 0 0 0 0 0
0 0 0 1 0 0 0 1
0 0 0 1 0 0 1 0
深度优先遍历:
A B C E F D G H
广度优先遍历:
A B D C F G H E