圖的兩種存儲結構及四種形態——鄰接矩陣、鄰接表;有向圖、無向圖、有向網、無向網。

聲明: 代碼中有大量的註釋,因此此處就再也不做出大量的解釋了。ios

一 :鄰接矩陣存儲結構數組

1.首先是各類類型與宏的定義:ide

 1 #include <iostream>
 2 using namespace std;  3 //無窮大
 4 #define INFINITY INT_MAX
 5 //最大頂點個數
 6 #define MAX_VERTEX_NUM 20
 7 //頂點類型
 8 typedef char VertexType;  9 typedef int VRType; 10 typedef char infoType; 11  //圖的四種類型
12 typedef enum {DG = 1, DN, UDG, UDN} GraphKind; 13 
14 //弧的結構體定義
15 typedef struct ArcCell 16 { 17     // 對於網來講是權值;對於圖來講就是0或1
18  VRType adj; 19     //該弧相關信息的指針(如今暫且能夠理解爲字符指針)
20     infoType* info; 21 }ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 22 
23 //圖的結構體定義
24 typedef struct
25 { 26  VertexType vexs[MAX_VERTEX_NUM]; 27      //arcs能夠先簡單地理解爲一個數組名
28  AdjMatrix arcs; 29     //當前圖中的頂點數和弧數
30     int vexnum, arcnum; 31     //圖的種類標誌
32  GraphKind kind; 33 }MGraph;
View Code


2.接下來是函數聲明及main函數:函數

void CreateGraph(MGraph &G); void CreateUDN(MGraph &G); int LocateVex(MGraph G , int v1); void CreateUDG(MGraph &G); void CreateDG(MGraph &G); void CreateDN(MGraph &G); void Print(MGraph G); int main(void) { MGraph G; CreateGraph(G); return 0; }
View Code


3.最後就是各類自定義函數的定義了:spa

void CreateGraph(MGraph &G) { cout << "一、有向圖" << endl; cout << "二、有向網" << endl; cout << "三、無向圖" << endl; cout << "四、無向網" << endl; cout << "你須要建立哪種類型的圖?" << endl; //此處運用了強轉(不能直接從鍵盤上給枚舉變量賦值)
    cin >> (int&)G.kind; switch (G.kind) { case 1: return CreateDG(G); break; case 2: return CreateDN(G); break; case 3: return CreateUDG(G); break; case 4: return CreateUDN(G); break; } } //建立有向網
void CreateDN(MGraph &G) { cout << "該圖有多少頂點以及多少條弧?" << endl; cin >> G.vexnum  >> G.arcnum; cout << "請輸入頂點:" << endl; for(int i = 0; i < G.vexnum; i++) { //cin至關於c裏面的scanf函數
        cin >> G.vexs[i]; } for(int i = 0; i < G.vexnum; i++) { for(int j = 0; j < G.vexnum; j++) { //先假設每兩個點之間都沒有邊
            G.arcs[i][j].adj = INFINITY; } } cout << "請輸入各弧的兩個端點及其權值" << endl; VertexType v1, v2; //用於暫時存儲每條弧的權值
 VRType temp; int i, j; //有向網不具有對稱性
    for(int k = 0; k < G.arcnum; k++) { cin >> v1 >> v2 >> temp; //利用存儲頂點所用的一維數組中對應點的下標
        i = LocateVex(G, v1), j = LocateVex(G, v2), G.arcs[i][j].adj = temp; } Print(G); } //建立有向圖
void CreateDG(MGraph &G) { cout << "該圖有多少頂點以及多少條邊?" << endl; cin >> G.vexnum  >> G.arcnum; cout << "請輸入頂點:" << endl; for(int i = 0; i < G.vexnum; i++) { cin >> G.vexs[i]; } for(int i = 0; i < G.vexnum; i++) { for(int j = 0; j < G.vexnum; j++) { //先假定圖中沒有弧
            G.arcs[i][j].adj = 0; } } cout << "請輸入各弧的兩個端點" << endl; VertexType v1, v2; //用於暫時存儲每條弧的'權值'(存在即爲1,不然爲0) //由於temp的取值只能爲1或0,因此不須要再輸入
    VRType temp = 1; int i, j; //有向圖不具有對稱性
    for(int k = 0; k < G.arcnum; k++) { cin >> v1 >> v2; i = LocateVex(G, v1), j = LocateVex(G, v2), G.arcs[i][j].adj = temp; } Print(G); } //建立無向圖(對稱)
void CreateUDG(MGraph &G) { cout << "該圖有多少頂點以及多少條邊?" << endl; cin >> G.vexnum  >> G.arcnum; cout << "請輸入頂點:" << endl; for(int i = 0; i < G.vexnum; i++) { cin >> G.vexs[i]; } for(int i = 0; i < G.vexnum; i++) { for(int j = 0; j < G.vexnum; j++) { //先假設每兩個點之間都沒有邊
            G.arcs[i][j].adj = 0; } } cout << "請輸入各弧的兩個端點(下三角)" << endl; VertexType v1, v2; VRType temp = 1; int i, j; //考慮到無向圖具備對稱性(先只輸入(鄰接矩陣)下三角里存在的邊)
    for(int k = 0; k < G.arcnum; k++) { cin >> v1 >> v2; i = LocateVex(G, v1), j = LocateVex(G, v2), G.arcs[i][j].adj = temp; //將上三角里的每條弧一樣添加上權值
        G.arcs[j][i].adj = G.arcs[i][j].adj; } Print(G); } //建立無向網(對稱)
void CreateUDN(MGraph &G) { cout << "該圖有多少頂點以及多少條邊?" << endl; cin >> G.vexnum  >> G.arcnum; cout << "請輸入頂點:" << endl; for(int i = 0; i < G.vexnum; i++) { cin >> G.vexs[i]; } for(int i = 0; i < G.vexnum; i++) { for(int j = 0; j < G.vexnum; j++) { //先假設每兩個點之間都沒有邊(無窮遠)
            G.arcs[i][j].adj = INFINITY; } } cout << "請輸入各弧的兩個端點及其權值(下三角)" << endl; VertexType v1, v2; VRType temp; int i, j; //考慮到無向圖具備對稱性(先只輸入(鄰接矩陣)下三角里存在的邊)
    for(int k = 0; k < G.arcnum; k++) { cin >> v1 >> v2 >> temp; i = LocateVex(G, v1), j = LocateVex(G, v2), G.arcs[i][j].adj = temp; //將上三角里的每條弧一樣添加上權值
        G.arcs[j][i].adj = G.arcs[i][j].adj; } Print(G); } //返回該頂點在一維數組中的下標(固然每個人建立的一維數組能夠是不一樣的)
int LocateVex(MGraph G , int v1) { for(int i = 0; i < G.vexnum; i++) { if(G.vexs[i] == v1) return i; } } void Print(MGraph G) { cout << "存儲的一維數組以下:" << endl; for(int i = 0; i < G.vexnum; i++) { cout << G.vexs[i] << '\t'; } cout << endl; cout << "鄰接矩陣以下:" << endl; for(int i = 0; i < G.vexnum; i++) { for(int j = 0; j < G.vexnum; j++) { cout << G.arcs[i][j].adj << '\t'; } cout << endl; } }
View Code


二 :鄰接表存儲結構指針

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;  4 using std :: string;  5 typedef string InforType;  6 //頂點類型
 7 typedef char VertexType;  8 typedef int Status;  9 typedef enum {UDG = 1, DG, UDN, DN} GraphKind;  10 //最大頂點個數
 11 #define MAX_VERTEX_NUM 20
 12 #define ERROR -1
 13 #define OK 1
 14 //表節點的定義
 15 typedef struct ArcNode  16 {  17     //該弧所指向的頂點的位置(相對地址)
 18     int adjvex;  19     //指向下一條弧的指針
 20     struct ArcNode* nextarc;  21     //該弧相關信息的指針(例如權值)
 22  InforType info;  23 }ArcNode;  24 //頭節點的定義
 25 typedef struct VNode  26 {  27     //頂點信息
 28  VertexType data;  29     //指向第一條依附該頂點的弧的指針
 30     ArcNode* firstarc;  31 }VNode, AdjList[MAX_VERTEX_NUM];  32 //圖的定義
 33 typedef struct
 34 {  35     //存放頭節點的一維數組
 36  AdjList vertices;  37     //圖的當前頂點數和弧數
 38     int vexnum, arcnum;  39     //圖的種類標誌
 40  GraphKind kind;  41 }ALGraph;  42 void CreateGraph(ALGraph& G);  43 Status CreateUDN(ALGraph& G);  44 Status CreateUDG(ALGraph& G);  45 Status CreateDG(ALGraph& G);  46 Status CreateDN(ALGraph& G);  47 int LocateVex(VNode vertices[], int vexnum, VertexType e);  48 void Print(const ALGraph& G);  49 int main(void)  50 {  51  ALGraph G;  52  CreateGraph(G);  53     return 0;  54 }  55 void CreateGraph(ALGraph& G)  56 {  57     int reply;  58     cout << "1. 無向圖" << endl;  59     cout << "2. 有向圖" << endl;  60     cout << "3. 無向網" << endl;  61     cout << "4. 有向網" << endl;  62     //其實逆與正是差很少的,根本上仍是取決於用戶的輸入
 63     cout << "5. 逆有向網" << endl;  64     cout << "6. 逆有向圖" << endl;  65     cout << "你想建立哪種類型的圖?" << endl;  66     cin >> reply;  67     switch(reply)  68  {  69     case 1:  70  CreateUDG(G);  71         break;  72     case 2:  73  CreateDG(G);  74         break;  75     case 3:  76  CreateUDN(G);  77         break;  78     case 4:  79  CreateDN(G);  80         break;  81     case 5:  82  CreateDN(G);  83         break;  84     case 6:  85  CreateDG(G);  86         break;  87     default:  88         exit(-1);  89  }  90 }  91 //構造無向網
 92 Status CreateUDN(ALGraph& G)  93 {  94  VertexType e;  95     int num;  96     cout << "該圖共有多少個頂點、多少條弧?" << endl;  97     cin >> G.vexnum >> G.arcnum;  98     cout << "請輸入各頂點:" << endl;  99     for(int i = 0; i < G.vexnum; i++) 100  { 101         //注意存儲結構
102         cin >> G.vertices[i].data; 103         //先將頭節點的指針域設爲空
104         G.vertices[i].firstarc = NULL; 105  } 106     for(int i = 0; i < G.vexnum; i++) 107  { 108         //(強調引用) 109         //注意ptr是節點的指針(是節點類型的一部分)而不是‘指向’節點的指針 110         //因此接連各節點不想之前那樣簡單了
111         ArcNode* &ptr = G.vertices[i].firstarc; 112         cout << "請問以頂點" << G.vertices[i].data << "爲起點的弧一共有多少條?" << endl; 113         cin >> num; 114         if(num > 0) 115  { 116             int Index; 117             ArcNode* p = NULL; 118             cout << "請將這些頂點及弧所帶信息依次輸入:" << endl; 119             //先處理一個節點(爲了方便後面的操做)
120             ptr = new ArcNode; 121             if(ptr) 122  { 123                 cin >> e; 124                 //輸入弧上的信息
125                 cin >> ptr->info; 126                 Index = LocateVex(G.vertices, G.vexnum, e); 127                 p = ptr; 128                 p->adjvex = Index; 129                 p->nextarc = NULL; 130  } 131             else
132                 return ERROR; 133             for(int j = 1; j < num; j++) 134  { 135                 ArcNode* ptr2 = new ArcNode; 136                 if(ptr2) 137  { 138                     //注意各變量的類型,不要搞混了
139                     cin >> e; 140                     //輸入弧上的信息
141                     cin >> ptr2->info; 142                     Index = LocateVex(G.vertices, G.vexnum, e); 143                     ptr2->adjvex = Index; 144                     ptr2->nextarc = NULL; 145                     //注意此處的鏈接節點與之前寫的有點不一樣(ptr‘一直’爲空)
146                     p->nextarc = ptr2; 147                     p = p->nextarc; 148  } 149                 else
150                     return ERROR; 151  } 152  } 153  } 154  Print(G); 155     return OK; 156 } 157 //構造無向圖
158 Status CreateUDG(ALGraph& G) 159 { 160  VertexType e; 161     int num; 162     cout << "該圖共有多少個頂點、多少條弧?" << endl; 163     cin >> G.vexnum >> G.arcnum; 164     cout << "請輸入各頂點:" << endl; 165     for(int i = 0; i < G.vexnum; i++) 166  { 167         //注意存儲結構
168         cin >> G.vertices[i].data; 169         //先將頭節點的指針域設爲空
170         G.vertices[i].firstarc = NULL; 171  } 172     for(int i = 0; i < G.vexnum; i++) 173  { 174         //(強調引用) 175         //注意ptr是節點的指針(是節點類型的一部分)而不是‘指向’節點的指針 176         //因此接連各節點不想之前那樣簡單了
177         ArcNode* &ptr = G.vertices[i].firstarc; 178         cout << "請問以頂點" << G.vertices[i].data << "爲起點的弧一共有多少條?" << endl; 179         cin >> num; 180         if(num > 0) 181  { 182             int Index; 183             ArcNode* p = NULL; 184             cout << "請將這些頂點依次輸入:" << endl; 185             //先處理一個節點(爲了方便後面的操做)
186             ptr = new ArcNode; 187             if(ptr) 188  { 189                 cin >> e; 190                 Index = LocateVex(G.vertices, G.vexnum, e); 191                 p = ptr; 192                 p->adjvex = Index; 193                 p->nextarc = NULL; 194  } 195             else
196                 return ERROR; 197             for(int j = 1; j < num; j++) 198  { 199                 //注意各變量的類型,不要搞混了
200                 cin >> e; 201                 Index = LocateVex(G.vertices, G.vexnum, e); 202                 ArcNode* ptr2 = new ArcNode; 203                 if(ptr2) 204  { 205                     ptr2->adjvex = Index; 206                     ptr2->nextarc = NULL; 207                     //注意此處的鏈接節點與之前寫的有點不一樣(ptr‘一直’爲空)
208                     p->nextarc = ptr2; 209                     p = p->nextarc; 210  } 211                 else
212                     return ERROR; 213  } 214  } 215  } 216  Print(G); 217     return OK; 218 } 219 //構造有向圖
220 Status CreateDG(ALGraph& G) 221 { 222  VertexType e; 223     int num; 224     cout << "該圖共有多少個頂點、多少條弧?" << endl; 225     cin >> G.vexnum >> G.arcnum; 226     cout << "請輸入各頂點:" << endl; 227     for(int i = 0; i < G.vexnum; i++) 228  { 229         //注意存儲結構
230         cin >> G.vertices[i].data; 231         //先將頭節點的指針域設爲空
232         G.vertices[i].firstarc = NULL; 233  } 234     for(int i = 0; i < G.vexnum; i++) 235  { 236         //(強調引用) 237         //注意ptr是節點的指針(是節點類型的一部分)而不是‘指向’節點的指針 238         //因此接連各節點不想之前那樣簡單了
239         ArcNode* &ptr = G.vertices[i].firstarc; 240         cout << "請問以頂點" << G.vertices[i].data << "爲起點的弧一共有多少條?" << endl; 241         cin >> num; 242         if(num > 0) 243  { 244             int Index; 245             ArcNode* p = NULL; 246             cout << "請將這些頂點依次輸入:" << endl; 247             //先處理一個節點(爲了方便後面的操做)
248             ptr = new ArcNode; 249             if(ptr) 250  { 251                 cin >> e; 252                 Index = LocateVex(G.vertices, G.vexnum, e); 253                 p = ptr; 254                 p->adjvex = Index; 255                 p->nextarc = NULL; 256  } 257             else
258                 return ERROR; 259             for(int j = 1; j < num; j++) 260  { 261                 //注意各變量的類型,不要搞混了
262                 cin >> e; 263                 Index = LocateVex(G.vertices, G.vexnum, e); 264                 ArcNode* ptr2 = new ArcNode; 265                 if(ptr2) 266  { 267                     ptr2->adjvex = Index; 268                     ptr2->nextarc = NULL; 269                     //注意此處的鏈接節點與之前寫的有點不一樣(ptr‘一直’爲空)
270                     p->nextarc = ptr2; 271                     p = p->nextarc; 272  } 273                 else
274                     return ERROR; 275  } 276  } 277  } 278  Print(G); 279     return OK; 280 } 281 //構造有向網
282 Status CreateDN(ALGraph& G) 283 { 284  VertexType e; 285     int num; 286     cout << "該圖共有多少個頂點、多少條弧?" << endl; 287     cin >> G.vexnum >> G.arcnum; 288     cout << "請輸入各頂點:" << endl; 289     for(int i = 0; i < G.vexnum; i++) 290  { 291         //注意存儲結構
292         cin >> G.vertices[i].data; 293         //先將頭節點的指針域設爲空
294         G.vertices[i].firstarc = NULL; 295  } 296     for(int i = 0; i < G.vexnum; i++) 297  { 298         //(強調引用) 299         //注意ptr是節點的指針(是節點類型的一部分)而不是‘指向’節點的指針 300         //因此接連各節點不想之前那樣簡單了
301         ArcNode* &ptr = G.vertices[i].firstarc; 302         cout << "請問以頂點" << G.vertices[i].data << "爲起點的弧一共有多少條?" << endl; 303         cin >> num; 304         if(num > 0) 305  { 306             int Index; 307             ArcNode* p = NULL; 308             cout << "請將這些頂點及弧所帶信息依次輸入:" << endl; 309             //先處理一個節點(爲了方便後面的操做)
310             ptr = new ArcNode; 311             if(ptr) 312  { 313                 cin >> e; 314                 //輸入弧上的信息
315                 cin >> ptr->info; 316                 Index = LocateVex(G.vertices, G.vexnum, e); 317                 p = ptr; 318                 p->adjvex = Index; 319                 p->nextarc = NULL; 320  } 321             else
322                 return ERROR; 323             for(int j = 1; j < num; j++) 324  { 325                 ArcNode* ptr2 = new ArcNode; 326                 if(ptr2) 327  { 328                     //注意各變量的類型,不要搞混了
329                     cin >> e; 330                     //輸入弧上的信息
331                     cin >> ptr2->info; 332                     Index = LocateVex(G.vertices, G.vexnum, e); 333                     ptr2->adjvex = Index; 334                     ptr2->nextarc = NULL; 335                     //注意此處的鏈接節點與之前寫的有點不一樣(ptr‘一直’爲空)
336                     p->nextarc = ptr2; 337                     p = p->nextarc; 338  } 339                 else
340                     return ERROR; 341  } 342  } 343  } 344  Print(G); 345     return OK; 346 } 347 //定位頂點在一維數組中的位置
348 int LocateVex(VNode vertices[], int vexnum, VertexType e) 349 { 350     int i; 351     for(i = 0; i < vexnum; i++) 352  { 353         if(vertices[i].data == e) 354             break; 355  } 356     return i; 357 } 358 //打印圖
359 void Print(const ALGraph& G) 360 { 361     cout << "您所建立的圖用鄰接表存儲結構展現以下:" << endl; 362     for(int i = 0; i < G.vexnum; i++) 363  { 364         cout  << "[" << G.vertices[i].data << "]"; 365         ArcNode* ptr = G.vertices[i].firstarc; 366         while(ptr) 367  { 368             //打印出下標(從零開始)
369             cout  << "—>" << ptr->adjvex; 370             ptr = ptr->nextarc; 371  } 372         cout << endl; 373  } 374 }
View Code
相關文章
相關標籤/搜索