圖->存儲結構->鄰接多重表


文字描述

  鄰接多重表是無向圖的另一種鏈式存儲結構. 雖然鄰接表是無向圖的一種很有效的存儲結構,在鄰接表中容易求得頂點和邊的各種信息. 但是,在鄰接表中每一條邊(vi,vj)有兩個結點,分別在第i個和第j個鏈表中,這給某些圖的操作帶來不便。如對已被搜索過的邊作記號或刪除一條邊等,此時需要找到表示同一條邊的兩個結點。因此,在進行這類操作的無向圖的問題中采用鄰接多重表更合適。

  鄰接多重表的結構和十字鏈表類型。邊結點和頂點結點如下示:

  

  

  邊結點由6個域組成:mark為標志域,可標記這條邊是否被搜索過; ivex和jvex為該邊依附的兩個頂點在圖中的位置;ilink指向下一條依附於頂點ivex的邊;jlink指向下一條依附於頂點jvex的邊,info為指向和邊相關的各種信息的指針域。

  頂點結點由2個域組成:data存儲和該頂點相關的信息如頂點名稱;firstedge域指示第一條依附於該頂點的邊。

示意圖

算法分析

  建立鄰接多重鏈表的時間復雜度和建立鄰接表是相同的. 另外鄰接多重表幾乎只針對無向圖或無向網。

代碼實現

 

  1 /*
  2     以鄰接多重表作為圖的存儲結構創建無向圖。
  3 */
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <string.h>
  7 
  8 #define    MAX_VERTEX_NUM    20
  9 typedef enum {DG, DN, UDG, UDN} GraphKind;
 10 typedef enum {unvisited, visited} VisitIf;
 11 typedef char InfoType;
 12 typedef char VertexType;
 13 //頂點結點
 14 typedef struct EBox{
 15     VisitIf mark;//訪問標記
 16     int ivex, jvex;//該邊依附的兩個頂點的位置
 17     struct EBox *ilink, *jlink;//分別指向依附這兩個頂點的下一條邊
 18     InfoType *info;//該邊信息指針
 19 }EBox;
 20 //邊結點
 21 typedef struct VexBox{
 22     VertexType data;//存儲頂點名稱
 23     EBox *firstedge;//指向第一條依附該頂點的邊
 24 }VexBox;
 25 //圖結點
 26 typedef struct{
 27     VexBox adjmulist[MAX_VERTEX_NUM];
 28     int vexnum,edgenum;    //無向圖的當前頂點數和邊數
 29     GraphKind kind;
 30 }AMLGraph;
 31 
 32 /*
 33     若G中存在頂點u,則返回該頂點在圖中位置;否則返回-1。
 34 */
 35 int LocateVex(AMLGraph G, VertexType v)
 36 {
 37     int i = 0;
 38     for(i=0; i<G.vexnum; i++){
 39         if(v == G.adjmulist[i].data)
 40             return i;
 41     }
 42     return -1;
 43 }
 44 
 45 /*
 46     若G中存在頂點位置loc存在,則返回其頂點名稱
 47 */
 48 VertexType LocateVInfo(AMLGraph G, int loc){
 49     return G.adjmulist[loc].data;
 50 }
 51 
 52 /*
 53     采用鄰接多重表的存儲結構,構造無向圖
 54  */
 55 int CreateUDG(AMLGraph *G)
 56 {
 57     int i = 0, j = 0, k = 0, IncInfo = 0;
 58     int vi = 0, vj = 0;
 59     char tmp[10] = {0};
 60     EBox *p = NULL;
 61     
 62     printf("輸入頂點數,邊數,其他信息標志位: ");
 63     scanf("%d,%d,%d", &G->vexnum, &G->edgenum, &IncInfo);
 64 
 65     for(i=0; i<G->vexnum; i++){
 66         //輸入頂點值
 67         printf("輸入第%d個頂點: ", i+1);
 68         memset(tmp, 0, sizeof(tmp));
 69         scanf("%s", tmp);
 70         G->adjmulist[i].data = tmp[0];
 71         G->adjmulist[i].firstedge = NULL;
 72     }
 73     for(k=0; k<G->edgenum; k++){
 74         printf("輸入第%d條邊(頂點1, 頂點2): ", k+1);
 75         memset(tmp, 0, sizeof(tmp));
 76         scanf("%s", tmp);
 77         sscanf(tmp, "%c,%c", &vi, &vj);
 78         i = LocateVex(*G, vi);
 79         j = LocateVex(*G, vj);
 80         p = (EBox*)malloc(sizeof(EBox));
 81         p->ivex = i;
 82         p->jvex = j;
 83         p->mark = unvisited;
 84         p->ilink = G->adjmulist[i].firstedge;
 85         p->jlink = G->adjmulist[j].firstedge;
 86         G->adjmulist[i].firstedge = p;
 87         G->adjmulist[j].firstedge = p;
 88         if(IncInfo){
 89             //Input(p->info);
 90         }
 91     }
 92     return 0;
 93 }
 94 
 95 /*
 96     采用鄰接多重表的存儲結構,構造圖
 97 */
 98 int CreateGrap(AMLGraph *G)
 99 {
100     printf("輸入圖類型: -有向圖(0), -有向網(1), +無向圖(2), -無向網(3): ");
101     scanf("%d", &G->kind);
102     switch(G->kind){
103         case DG:
104         case DN:
105         default:
106             printf("還不支持!\n");
107             return -1;
108         case UDG:
109             return CreateUDG(G);
110     }
111     return 0;
112 }
113 
114 /*
115     輸出圖的信息
116 */
117 void printG(AMLGraph G)
118 {
119     if(G.kind == DG){
120         printf("類型:有向圖;頂點數 %d, 邊數 %d\n", G.vexnum, G.edgenum);
121     }else if(G.kind == DN){
122         printf("類型:有向網;頂點數 %d, 邊數 %d\n", G.vexnum, G.edgenum);
123     }else if(G.kind == UDG){
124         printf("類型:無向圖;頂點數 %d, 邊數 %d\n", G.vexnum, G.edgenum);
125     }else if(G.kind == UDN){
126         printf("類型:無向網;頂點數 %d, 邊數 %d\n", G.vexnum, G.edgenum);
127     }
128     int i = 0;
129     EBox *vi = NULL;
130     EBox *vj = NULL;
131     EBox *vf = NULL;
132     for(i=0; i<G.vexnum; i++){
133         printf("%c(%d): ", G.adjmulist[i].data, i);
134         vf = G.adjmulist[i].firstedge;
135         vi = vf->ilink;
136         vj = vf->jlink;
137         printf("fistedge:%c(%d)->%c(%d); ", LocateVInfo(G, vf->ivex), vf->ivex, LocateVInfo(G, vf->jvex), vf->jvex);
138         printf(" || ilink:");
139         while(vi){
140             printf("%c(%d)->%c(%d);", LocateVInfo(G, vi->ivex), vi->ivex, LocateVInfo(G, vi->jvex), vi->jvex);
141             vi = vi->ilink;
142         }
143         printf(" || jlink:");
144         while(vj){
145             printf("%c(%d)->%c(%d);", LocateVInfo(G, vj->ivex), vj->ivex, LocateVInfo(G, vj->jvex), vj->jvex);
146             vj = vj->jlink;
147         }
148         printf("\n");
149     }
150     return ;
151 }
152 
153 int main(int argc, char *argv[])
154 {
155     AMLGraph G;
156     if(CreateGrap(&G) > -1){
157         printG(G);
158     }
159     return 0;
160 }
鄰接多重表存儲結構(圖)

 

代碼運行

 


免責聲明!

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



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