Java實現圖的深度和廣度優先遍歷演算法
阿新 • • 發佈:2018-12-09
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-e2445db1a8.css">
<div class="htmledit_views">
概述:
最近要學習寫網路爬蟲,所以把圖的深度和廣度搜索都再溫習一下。
圖結構展示:
實現過程:
首先,我們來看看圖結構在程式碼中的實現。有三塊邏輯:
1.圖中的節點:
- public class GraphNode {
- public List<GraphEdge> edgeList = null;
- private String label = "";
- public GraphNode(String label) {
- this.label = label;
- if (edgeList == null) {
- edgeList = new ArrayList<GraphEdge>();
- }
- }
- /**
- * 給當前節點新增一條邊
- * GraphNode
- * @param
edge - * 新增的邊
- */
- public void addEdgeList(GraphEdge edge) {
- edgeList.add(edge);
- }
- public String getLabel() {
- return label;
- }
- }
2.圖中的邊:
- public class GraphEdge {
- private GraphNode nodeLeft;
- private GraphNode nodeRight;
- /**
- * @param nodeLeft
- * 邊的左端
- * @param
nodeRight - * 邊的右端
- */
- public GraphEdge(GraphNode nodeLeft, GraphNode nodeRight) {
- this.nodeLeft = nodeLeft;
- this.nodeRight = nodeRight;
- }
- public GraphNode getNodeLeft() {
- return nodeLeft;
- }
- public GraphNode getNodeRight() {
- return nodeRight;
- }
- }
3.把節點和邊組合成一個圖結構:
- public class MyGraph {
- private List<GraphNode> nodes = null;
- public void initGraph(int n) {
- if (nodes == null) {
- nodes = new ArrayList<GraphNode>();
- }
- GraphNode node = null;
- for (int i = 0; i < n; i++) {
- node = new GraphNode(String.valueOf(i));
- nodes.add(node);
- }
- }
- public void initGraph(int n, boolean b) {
- initGraph(n);
- GraphEdge edge01 = new GraphEdge(nodes.get(0), nodes.get(1));
- GraphEdge edge02 = new GraphEdge(nodes.get(0), nodes.get(2));
- GraphEdge edge13 = new GraphEdge(nodes.get(1), nodes.get(3));
- GraphEdge edge14 = new GraphEdge(nodes.get(1), nodes.get(4));
- GraphEdge edge25 = new GraphEdge(nodes.get(2), nodes.get(5));
- GraphEdge edge26 = new GraphEdge(nodes.get(2), nodes.get(6));
- GraphEdge edge37 = new GraphEdge(nodes.get(3), nodes.get(7));
- GraphEdge edge47 = new GraphEdge(nodes.get(4), nodes.get(7));
- GraphEdge edge56 = new GraphEdge(nodes.get(5), nodes.get(6));
- nodes.get(0).addEdgeList(edge01);
- nodes.get(0).addEdgeList(edge02);
- nodes.get(1).addEdgeList(edge13);
- nodes.get(1).addEdgeList(edge14);
- nodes.get(2).addEdgeList(edge25);
- nodes.get(2).addEdgeList(edge26);
- nodes.get(3).addEdgeList(edge37);
- nodes.get(4).addEdgeList(edge47);
- nodes.get(5).addEdgeList(edge56);
- }
- public void initGraph() {
- initGraph(8, false);
- }
- public List<GraphNode> getGraphNodes() {
- return nodes;
- }
- }
有了圖的結構,我們就可以進行一些實際的操作了。
深度優先搜尋:
- public class DFSearch {
- /**
- * 深度遍歷
- * DFSearch
- * @param node
- * 當前節點
- * @param visited
- * 被訪問過的節點列表
- */
- public void searchTraversing(GraphNode node, List<GraphNode> visited) {
- // 判斷是否遍歷過
- if (visited.contains(node)) {
- return;
- }
- visited.add(node);
- System.out.println("節點:" + node.getLabel());
- for (int i = 0; i < node.edgeList.size(); i++) {
- searchTraversing(node.edgeList.get(i).getNodeRight(), visited);
- }
- }
- }
廣度優先搜尋:
- public class BFSearch {
- /**
- * 廣度優先搜尋
- * BFSearch
- * @param node
- * 搜尋的入口節點
- */
- public void searchTraversing(GraphNode node) {
- List<GraphNode> visited = new ArrayList<GraphNode>(); // 已經被訪問過的元素
- Queue<GraphNode> q = new LinkedList<GraphNode>(); // 用佇列存放依次要遍歷的元素
- q.offer(node);
- while (!q.isEmpty()) {
- GraphNode currNode = q.poll();
- if (!visited.contains(currNode)) {
- visited.add(currNode);
- System.out.println("節點:" + currNode.getLabel());
- for (int i = 0; i < currNode.edgeList.size(); i++) {
- q.offer(currNode.edgeList.get(i).getNodeRight());
- }
- }
- }
- }
- }
執行結果:
原始碼下載:
</div>
</div>