數據結構之圖(2-2)【鄰接多重表】適用於無向圖


       鄰接多重表(Adjacency Multilist)主要用於存儲無向圖。因為,如果用鄰接表存儲無向圖,每條邊的兩個邊結點分別在以該邊

所依附的兩個頂點為頭結點的鏈表中,這給圖的某些操作帶來不便。例如,對已訪問過的邊做標記,或者要刪除圖中某一條邊等,

都需要找到表示同一條邊的兩個結點。因此,在進行這一類操作的無向圖的問題中采用鄰接多重表作存儲結構更為適宜。

 

       鄰接多重表的存儲結構和十字鏈表類似,也是由頂點表和邊表組成,每一條邊用一個結點表示,其頂點表結點結構和邊表結點

結構如圖8.15 所示。

其中,頂點表由兩個域組成,vertex 域存儲和該頂點相關的信息firstedge 域指示第一條依附於該頂點的邊;邊表結點由六個域

組成,mark 為標記域,可用以標記該條邊是否被搜索過;ivex 和jvex 為該邊依附的兩個頂點在圖中的位置;ilink 指向下一條依

附於頂點ivex的邊;jlink 指向下一條依附於頂點jvex 的邊,info 為指向和邊相關的各種信息的指針域。

例如,圖8.16 所示為無向圖8.1 的鄰接多重表。在鄰接多重表中,所有依附於同一頂點的邊串聯在同一鏈表中,由於每條邊依附於兩個頂

點,則每個邊結點同時鏈接在兩個鏈表中。可見,對無向圖而言,其鄰接多重表和鄰接表的差別,僅僅在於同一條邊在鄰接表中用兩個結

點表示,而在鄰接多重表中只有一個結點。因此,除了在邊結點中增加一個標志域外,鄰接多重表所需的存儲量和鄰接表相同。在鄰接多

重表上,各種基本操作的實現亦和鄰接表相似。

代碼如下:

  1 #include "stdafx.h"
  2 #include<iostream>
  3 using namespace std;
  4 
  5 typedef int VertexType;
  6 #define MAX_VERTEX_NUM 20
  7 typedef enum{unvisited,visited} VisitIf;
  8 typedef struct EBox
  9 {
 10     VisitIf mark;            //訪問標記 
 11     int ivex, jvex;          //該邊依附的兩個頂點的位置
 12     struct EBox *ilink, *jlink;//分別指向依附的兩個頂點的下一條邊
 13     int info;                //該邊信息指針,可指向權值或其他信息
 14 }EBox;
 15 typedef struct VexBox
 16 {
 17     VertexType data;         
 18     EBox *firstarc;          //指向第一條依附改點的邊
 19 }VexBox;
 20 typedef struct
 21 {
 22     VexBox adjmulist[MAX_VERTEX_NUM];
 23     int vexnum, arcnum;      //無向圖的當前頂點數和邊數
 24 }AMLGraph;
 25 
 26 int LocateVex(AMLGraph G, VertexType v)// 初始條件:無向圖G存在,v和G中頂點有相同特征  
 27                                        // 操作結果:若G中存在頂點v,則返回該頂點在無向圖中位置;否則返回-1  
 28 {
 29     for (int i = 0; i < G.vexnum; i++)
 30         if (G.adjmulist[i].data == v)
 31             return i;
 32     return -1;
 33 }
 34 
 35 void CreateGraph(AMLGraph &G)//采用鄰接多重表構建無向圖G
 36 {
 37     VertexType v1, v2;
 38     cout << "請輸入總頂點數和總邊數(用空格隔開):";
 39     cin >> G.vexnum >> G.arcnum;
 40     cout << "輸入頂點" << endl;
 41     for (int i = 0; i < G.vexnum; i++)//構造頂點向量
 42     {
 43         cin >> G.adjmulist[i].data ;
 44         G.adjmulist[i].firstarc = NULL;
 45     }
 46     cout << "請輸入每條邊的兩個端點以及權值:" << endl;
 47     for (int k = 0; k < G.arcnum; k++)//構造表結點鏈表
 48     {
 49         EBox *p = new EBox;;
 50         cin >> v1 >> v2 >>p->info;
 51         int m = LocateVex(G, v1);//一端
 52         int n = LocateVex(G, v2);//另一端
 53         p->mark = unvisited;
 54         p->ivex = m;         //插在一端表頭
 55         p->ilink = G.adjmulist[m].firstarc;
 56         G.adjmulist[m].firstarc = p;
 57         p->jvex = n;         //插在另一端表頭
 58         p->jlink = G.adjmulist[n].firstarc;
 59         G.adjmulist[n].firstarc = p;
 60     }
 61 }
 62 
 63 void MarkUnvizited(AMLGraph G)//置邊的訪問標記為未被訪問
 64 {   
 65     int i;
 66     EBox *p;
 67     for (i = 0; i<G.vexnum; i++)
 68     {
 69         p = G.adjmulist[i].firstarc;
 70         while (p)
 71         {
 72             p->mark = unvisited;
 73             if (p->ivex == i)
 74                 p = p->ilink;
 75             else
 76                 p = p->jlink;
 77         }
 78     }
 79 }
 80 
 81 
 82 void display(AMLGraph G)//輸出無向圖的鄰接多重表
 83 {
 84     EBox *p;
 85     MarkUnvizited(G);
 86     cout << "無向圖有" << G.vexnum << "個頂點,分別為:";
 87     for (int i = 0; i < G.vexnum; i++)
 88     {
 89         cout << G.adjmulist[i].data << " ";
 90         
 91     }
 92         cout << endl;
 93         for (int i = 0; i < G.vexnum; i++)
 94         {
 95             cout << "" << G.adjmulist[i].data << "有關的邊:";
 96             p = G.adjmulist[i].firstarc;
 97             while (p)
 98             {
 99                 if (p->ivex == i) // 邊的m端與該頂點有關
100                 {
101                     if (p->mark)
102                     {
103                         cout << G.adjmulist[i].data <<" "<< G.adjmulist[p->jvex].data<<"   ";
104                         p->mark = visited;
105                         if (p->info)
106                             cout << "權值:" << p->info << ". ";
107                     }
108                     p = p->ilink;
109                 }
110                 else              // 邊的n端與該頂點有關
111                 {
112                     if (!p->mark)
113                     {
114                         cout << G.adjmulist[p->ivex].data <<" "<< G.adjmulist[i].data<<"   ";
115                         p->mark = visited;
116                         if (p->info)
117                             cout << "權值:" << p->info << ". ";
118                     }
119                     p = p->jlink;
120                 }
121             }
122             cout << endl;
123         }
124 }
125 
126 int main()
127 {
128     AMLGraph MG;
129     CreateGraph(MG);
130     display(MG);
131     return 0;
132 }

 

輸出結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM