以鄰接表的形式建立帶權值的有向圖即有向網

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

自行輸入的運行結果以下:指針

相關文章
相關標籤/搜索