1. 程式人生 > >9、【資料結構】圖之鄰接矩陣、鄰接表有向圖

9、【資料結構】圖之鄰接矩陣、鄰接表有向圖

一、鄰接矩陣有向圖

1、基本定義
#define MAX 10

class MatrixDG {
private:
    char mVexs[MAX];         // 頂點集合
    int mVexNum;             // 頂點數
    int mEdgNum;             // 邊數
    int mMatrix[MAX][MAX];   // 鄰接矩陣

public:
    // 建立圖(自己輸入資料)
    MatrixDG();
    // 建立圖(用已提供的矩陣)
    MatrixDG(char vexs[], int vlen, char edges[
][2], int elen); ~MatrixDG(); // 列印矩陣佇列圖 void print(); private: // 讀取一個輸入字元 char readChar(); // 返回ch在mMatrix矩陣中的位置 int getPosition(char ch); };

    MatrixDG是鄰接矩陣有向圖對應的結構體。     mVexs用於儲存頂點,mVexNum是頂點數,mEdgNum是邊數;mMatrix則是用於儲存矩陣資訊的二維陣列。例如,mMatrix[i][j]=1,則表示"頂點i(即mVexs[i])"和"頂點j(即mVexs[j])"是鄰接點,且頂點i是起點,頂點j是終點。

2、建立矩陣
2.1 建立圖(用已提供的矩陣)
/*
 * 建立圖(用已提供的矩陣)
 *
 * 引數說明:
 *     vexs  -- 頂點陣列
 *     vlen  -- 頂點陣列的長度
 *     edges -- 邊陣列
 *     elen  -- 邊陣列的長度
 */
MatrixDG::MatrixDG(char vexs[], int vlen, char edges[][2], int elen)
{
    int i, p1, p2;

    // 初始化"頂點數"和"邊數"
    mVexNum = vlen;
    mEdgNum = elen;
    // 初始化"頂點"
for (i = 0; i < mVexNum; i++) mVexs[i] = vexs[i]; // 初始化"邊" for (i = 0; i < mEdgNum; i++) { // 讀取邊的起始頂點和結束頂點 p1 = getPosition(edges[i][0]); p2 = getPosition(edges[i][1]); mMatrix[p1][p2] = 1; } }

    該函式的作用是根據已有資料建立一個鄰接矩陣有向圖。

2.2 建立圖(自己輸入)
/*
 * 建立圖(自己輸入資料)
 */
MatrixDG::MatrixDG()
{
    char c1, c2;
    int i, p1, p2;

    // 輸入"頂點數"和"邊數"
    cout << "input vertex number: ";
    cin >> mVexNum;
    cout << "input edge number: ";
    cin >> mEdgNum;
    if ( mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum-1))))
    {
        cout << "input error: invalid parameters!" << endl;
        return ;
    }

    // 初始化"頂點"
    for (i = 0; i < mVexNum; i++)
    {
        cout << "vertex(" << i << "): ";
        mVexs[i] = readChar();
    }

    // 初始化"邊"
    for (i = 0; i < mEdgNum; i++)
    {
        // 讀取邊的起始頂點和結束頂點
        cout << "edge(" << i << "): ";
        c1 = readChar();
        c2 = readChar();

        p1 = getPosition(c1);
        p2 = getPosition(c2);
        if (p1==-1 || p2==-1)
        {
            cout << "input error: invalid edge!" << endl;
            return ;
        }

        mMatrix[p1][p2] = 1;
    }
}

    該函式是讀取使用者的輸入,將輸入的資料轉換成對應的有向圖。

二、鄰接表有向圖

1、基本定義
#define MAX 100

// 鄰接表中表對應的連結串列的頂點
struct ENode
{
    int ivex;           // 該邊所指向的頂點的位置
    ENode *nextEdge;    // 指向下一條弧的指標
};

// 鄰接表中表的頂點
struct VNode
{
    char data;          // 頂點資訊
    ENode *firstEdge;   // 指向第一條依附該頂點的弧
};


// 鄰接表
class ListDG
{

private: // 私有成員
    int mVexNum;             // 圖的頂點的數目
    int mEdgNum;             // 圖的邊的數目
    VNode mVexs[MAX];

public:
    // 建立鄰接表對應的圖(自己輸入)
    ListDG();
    // 建立鄰接表對應的圖(用已提供的資料)
    ListDG(char vexs[], int vlen, char edges[][2], int elen);
    ~ListDG();

    // 列印鄰接表圖
    void print();

private:
    // 讀取一個輸入字元
    char readChar();
    // 返回ch的位置
    int getPosition(char ch);
    // 將node節點連結到list的最後
    void linkLast(ENode *list, ENode *node);
};

    (1) ListDG是鄰接表對應的結構體。 mVexNum是頂點數,mEdgNum是邊數;mVexs則是儲存頂點資訊的一維陣列。     (2) VNode是鄰接表頂點對應的結構體。 data是頂點所包含的資料,而firstEdge是該頂點所包含連結串列的表頭指標。     (3) ENode是鄰接表頂點所包含的連結串列的節點對應的結構體。 ivex是該節點所對應的頂點在vexs中的索引,而nextEdge是指向下一個節點的。

2、建立鄰接表
2.1 建立圖(用已提供的資料)
/*
 * 建立鄰接表對應的圖(用已提供的資料)
 */
ListDG::ListDG(char vexs[], int vlen, char edges[][2], int elen)
{
    char c1, c2;
    int p1, p2;
    ENode *node1;

    // 初始化"頂點數"和"邊數"
    mVexNum = vlen;
    mEdgNum = elen;
    // 初始化"鄰接表"的頂點
    for(int i=0; i<mVexNum; i++)
    {
        mVexs[i].data = vexs[i];
        mVexs[i].firstEdge = NULL;
    }

    // 初始化"鄰接表"的邊
    for(int i=0; i<mEdgNum; i++)
    {
        // 讀取邊的起始頂點和結束頂點
        c1 = edges[i][0];
        c2 = edges[i][1];

        p1 = getPosition(c1);
        p2 = getPosition(c2);
        // 初始化node1
        node1 = new ENode();
        node1->ivex = p2;
        // 將node1連結到"p1所在連結串列的末尾"
        if(mVexs[p1].firstEdge == NULL)
          mVexs[p1].firstEdge = node1;
        else
            linkLast(mVexs[p1].firstEdge, node1);
    }
}

    該函式的作用是根據已有資料建立一個鄰接表有向圖。

2.2 建立圖(自己輸入)
/*
 * 建立鄰接表對應的圖(自己輸入)
 */
ListDG::ListDG()
{
    char c1, c2;
//    int v, e;
    int p1, p2;
    ENode *node1;

    // 輸入"頂點數"和"邊數"
    cout << "input vertex number: ";
    cin >> mVexNum;
    cout << "input edge number: ";
    cin >> mEdgNum;
    if ( mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum-1))))
    {
        cout << "input error: invalid parameters!" << endl;
        return ;
    }

    // 初始化"鄰接表"的頂點
    for(int i=0; i<mVexNum; i++)
    {
        cout << "vertex(" << i << "): ";
        mVexs[i].data = readChar();
        mVexs[i].firstEdge = NULL;
    }

    // 初始化"鄰接表"的邊
    for(int i=0; i<mEdgNum; i++)
    {
        // 讀取邊的起始頂點和結束頂點
        cout << "edge(" << i << "): ";
        c1 = readChar();
        c2 = readChar();

        p1 = getPosition(c1);
        p2 = getPosition(c2);
        // 初始化node1
        node1 = new ENode();
        node1->ivex = p2;
        // 將node1連結到"p1所在連結串列的末尾"
        if(mVexs[p1].firstEdge == NULL)
          mVexs[p1].firstEdge = node1;
        else
            linkLast(mVexs[p1].firstEdge, node1);
    }
}

    該函式是讀取使用者的輸入,將輸入的資料轉換成對應的有向圖。 鄰接矩陣有向圖完整示例程式碼: 鄰接表有向圖完整示例程式碼: