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
自行输入的运行结果以下:指针