大話資料結構--圖的遍歷-java實現
阿新 • • 發佈:2018-11-10
圖的遍歷分為深度優先遍歷和廣度優先遍歷
總結下圖的遍歷:
- 深度優先遍歷
就像一棵樹的前序遍歷
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