聲明: 代碼中有大量的註釋,因此此處就再也不做出大量的解釋了。ios
一 :鄰接矩陣存儲結構數組
1.首先是各類類型與宏的定義:ide
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
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;
2.接下來是函數聲明及main函數:函數
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
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; }
3.最後就是各類自定義函數的定義了:spa
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
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; } }
二 :鄰接表存儲結構指針
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
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 }