1.有向網的數據結構java
單鏈表中的每一個結點有3個域組成,分別爲鄰接點域(adjvex)表示與某頂點鄰接的點在圖中的位置;鏈域(nextarc)表示下一條邊或弧的結點;數據域info存儲和邊或弧相關的信息,如權值等。node
每一個鏈表上附設一個表頭結點。在表頭結點中,除了設有鏈域(firstarc)指向鏈表中的第一個結點以外,還設有存儲頂點的名或其餘相關信息的數據域data.數組
// 鄰接表中表對應的鏈表的頂點 private class ENode { int ivex; // 該邊所指向的頂點的位置,若是該結點爲B,而圖的頂點數組中B的索引爲1,則此時的ivex值就位1 ENode nextEdge; // 指向下一條弧的指針, int weight; //權值,頂點到該結點的權值,距離 } // 鄰接表中表的頂點(頭結點) private class VNode { String data; // 頂點信息,名字或者其餘,如A,B,C,V0,V1等 ENode firstEdge; // 指向第一條依附該頂點的弧,若是該頂點下沒有鏈表,則爲null } private VNode[] mVexs; // 頂點數組,存取圖的各個頂點
2.附上代碼:數據結構
package com.test.frame.fighting.graph; import java.io.IOException; import java.util.ArrayList; import java.util.Scanner; /** * ListDG class * * @author guanhuifang * @date 2018/1/19 下午8:20 **/ public class ListDG { // 鄰接表中表對應的鏈表的頂點 private class ENode { int ivex; // 該邊所指向的頂點的位置 ENode nextEdge; // 指向下一條弧的指針 int weight; //權值,頂點到該節點的權值,距離 } // 鄰接表中表的頂點(頭結點) private class VNode { String data; // 頂點信息 ENode firstEdge; // 指向第一條依附該頂點的弧 } private VNode[] mVexs; // 頂點數組 /** * 建立圖,輸入數據 */ public ListDN() { // 輸入"頂點數"和"邊數" System.out.printf("input vertex number: "); int vlen = readInt(); System.out.printf("input edge number: "); int elen = readInt(); if (vlen < 1 || elen < 1 || (elen > (vlen * (vlen - 1)))) { System.out.printf("input error: invalid parameters!\n"); return; } // 初始化"頂點" mVexs = new VNode[vlen]; for (int i = 0; i < mVexs.length; i++) { System.out.printf("vertex(%d): ", i); mVexs[i] = new VNode(); mVexs[i].data = String.valueOf(readChar()); mVexs[i].firstEdge = null; } // 初始化"邊" for (int i = 0; i < elen; i++) { // 讀取邊的起始頂點和結束頂點 System.out.printf("edge(%d):", i); String c1 = String.valueOf(readChar()); String c2 = String.valueOf(readChar()); int weight = readInt(); System.out.println(c2 + "——>" + c2 + " weight:" + weight); int p1 = getPosition(c1); int p2 = getPosition(c2); // 初始化node1 ENode node1 = new ENode(); node1.ivex = p2; node1.weight = weight; // 將node1連接到"p1所在鏈表的末尾" if (mVexs[p1].firstEdge == null) { mVexs[p1].firstEdge = node1; } else { linkLast(mVexs[p1].firstEdge, node1); } } } /** * 建立圖,已知頂點和弧 * @param vexs 頂點數組 * @param edges 邊數組 */ public ListDG(String[] vexs, ArrayList<String> edges) { // 初始化"頂點數"和"邊數" int vlen = vexs.length; int elen = edges.size(); // 初始化"頂點" mVexs = new VNode[vlen]; for (int i = 0; i < mVexs.length; i++) { mVexs[i] = new VNode(); mVexs[i].data = vexs[i]; mVexs[i].firstEdge = null; } // 初始化"邊" for (int i = 0; i < elen; i++) { // 讀取邊的起始頂點和結束頂點 String c1 = edges.get(i).substring(0, 1); String c2 = edges.get(i).substring(1, 2); int weight = Integer.parseInt(edges.get(i).substring(2)); System.out.println(c1+c2+weight); // 讀取邊的起始頂點和結束頂點 int p1 = getPosition(c1); int p2 = getPosition(c2); // 初始化node1 ENode node1 = new ENode(); node1.ivex = p2; //ivex是指該邊指向頂點的位置 node1.weight = weight; node1.nextEdge = null; // 將node1連接到"p1所在鏈表的末尾" if (mVexs[p1].firstEdge == null) { //判斷起點是否爲頂點,若是是頭頂點,則把該頂點直接掛到該頭頂點的位置 mVexs[p1].firstEdge = node1; } else { /** * 若是找到頂點向量數組中的頂點不是頭結點,即他下面掛有結點,則把他下面 * 掛的第一個頂點,和該頂點 */ linkLast(mVexs[p1].firstEdge, node1); } } } /* * 將node節點連接到list的最後 */ private void linkLast(ENode list, ENode node) { ENode p = list; while (p.nextEdge != null) { p = p.nextEdge; } p.nextEdge = node; } /* * 返回ch位置 */ private int getPosition(String ch) { for (int i = 0; i < mVexs.length; i++) { if (mVexs[i].data.equals(ch)) { return i; } } return -1; } /* * 讀取一個輸入字符 */ private char readChar() { char ch = '0'; do { try { ch = (char) System.in.read(); } catch (IOException e) { e.printStackTrace(); } } while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))); return ch; } /* * 讀取一個輸入字符 */ private int readInt() { Scanner scanner = new Scanner(System.in); return scanner.nextInt(); } /* * 打印矩陣隊列圖 */ public void print() { System.out.printf("List Graph:\n"); for (int i = 0; i < mVexs.length; i++) { System.out.printf("%d(%s)-> ", i, mVexs[i].data); ENode node = mVexs[i].firstEdge; while (node != null) { System.out.printf("%d(%s)-%d ", node.ivex, mVexs[node.ivex].data,node.weight); node = node.nextEdge; } System.out.printf("\n"); } } }
3.測試測試
import com.test.frame.fighting.graph.ListDN; import org.junit.Test; import java.util.ArrayList; /** * ListDNTest class * * @author guanhuifang * @date 2018/1/19 下午10:19 **/ public class ListDNTest { @Test public void createListDN(){ String[] vexs = {"A", "B", "C", "D", "E"}; ArrayList<String> edgeList = new ArrayList<>(); edgeList.add("AB5"); edgeList.add("BC4"); edgeList.add("CD8"); edgeList.add("DC8"); edgeList.add("DE6"); edgeList.add("AD5"); edgeList.add("CE2"); edgeList.add("EB3"); edgeList.add("AE7"); // 採用已有的"圖" ListDN pN = new ListDN(vexs, edgeList); pN.print(); // 打印圖 } }
4.測試結果以下:ui
List Graph: 0(A)-> 1(B)-5 3(D)-5 4(E)-7 1(B)-> 2(C)-4 2(C)-> 3(D)-8 4(E)-2 3(D)-> 2(C)-8 4(E)-6 4(E)-> 1(B)-3 Process finished with exit code 0
自行輸入的運行結果以下:指針