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

8、【資料結構】圖之鄰接矩陣、鄰接表無向圖

一、鄰接矩陣無向圖

1、基本定義
#define MAX 10

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

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

    mVexs用於儲存頂點,mVexNum是頂點數,mEdgNum是邊數;mMatrix則是用於儲存矩陣資訊的二維陣列。例如,mMatrix[i][j]=1,則表示"頂點i(即mVexs[i])"和"頂點j(即mVexs[j])"是鄰接點;mMatrix[i][j]=0,則表示它們不是鄰接點。

2、建立矩陣
2.1 建立圖(用已提供的矩陣)
//建立圖(用已有矩陣進行初始化)
//  vexs:頂點陣列
//  vlen:頂點陣列的長度
//  edges:邊陣列
//  elen:邊陣列的長度
MatrixUDG::MatrixUDG(char vexs[], int vlen, char edges[][2], int elen)
{
  int p1, p2;
  //初始化頂點數和邊數
  mVexNum = vlen;
  mEdgNum = elen;

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

    該函式的作用是利用已知資料來建立一個鄰接矩陣無向圖。

2.2 建立圖(自己輸入)
//建立圖(自己輸入資料)
MatrixUDG::MatrixUDG()
{
    char ch1, ch2;
    int 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: invalide parameters!" << endl;
        return;
    }

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

        p1 = getPosition(ch1);
        p2 = getPosition(ch2);
        if(p1 == -1 || p2 == -1)
        {
            cout << "input error: invalide edge" << endl;
            return;
        }

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

    該函式要求使用者自己輸入資料來建立一個鄰接矩陣無向圖。 鄰接矩陣無向圖的完整示例程式碼地址:

二、鄰接表無向圖

1、基本定義
#define MAX 10

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

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

class ListUDG
{
private:
    int mVexNum;        //定點數
    int mEdgNum;       //邊數
    VNode mVexs[MAX];   //鄰接表中的頂點
public:
    //建立鄰接表對應的圖(自己輸入)
    ListUDG();
    //建立鄰接表對應的圖(用已有的資料)
    ListUDG(char vexs[], int vlen, char edges[][2], int elen);
    //解構函式
    ~ListUDG();
    //列印鄰接表圖
    void print();

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

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

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

    // 初始化"頂點數"和"邊數"
    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);
        // 初始化node2
        node2 = new ENode();
        node2->ivex = p1;
        // 將node2連結到"p2所在連結串列的末尾"
        if(mVexs[p2].firstEdge == NULL)
          mVexs[p2].firstEdge = node2;
        else
            linkLast(mVexs[p2].firstEdge, node2);
    }
}

    該函式的作用是利用已知資料來建立一個鄰接表無向圖。

2.2 建立圖(自己輸入)
ListUDG::ListUDG()
{
    char ch1, ch2;
    //int vex, edge;
    int p1, p2;
    ENode *node1, *node2;

    //輸入定點數和邊數
    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 << ")";
        ch1 = readChar();
        ch2 = readChar();

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

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

    該函式要求使用者自己輸入資料來建立一個鄰接表無向圖。     鄰接表無向圖的完整示例程式碼地址: