1. 程式人生 > >大話資料結構--圖的遍歷-java實現

大話資料結構--圖的遍歷-java實現

圖的遍歷分為深度優先遍歷和廣度優先遍歷

總結下圖的遍歷:

  • 深度優先遍歷
    這裡寫圖片描述
    這裡寫圖片描述
    就像一棵樹的前序遍歷
      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