生活随笔
收集整理的這篇文章主要介紹了
实验三 图的操作与实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
記錄實驗,同時也是記錄常見數據結構算法的實現。
廣州大學學生實驗報告
開課實驗室:計算機科學與工程實驗(電子樓416A)
學院 計算機科學與網絡工程學院
實驗課程 數據結構實驗
實驗項目 實驗三 圖的操作與實現
- 一、實驗目的:
1、圖的鄰接表和鄰接矩陣存儲
2、圖的各種遍歷算法實現
3、最小生成樹的算法實現
4、最短路徑的算法實現 - 二、使用儀器、器材
微機一臺
操作系統:Win10
編程軟件:C++ - 三、實驗內容及原理
1、圖的鄰接表和鄰接矩陣存儲 (返回目錄🖱)
建立下圖的鄰接表或鄰接矩陣,并輸出之;
#include <iostream>
using namespace std
;#define MaxInt 32767
#define MVNum 100 typedef struct AMGraph
{char vexs
[MVNum
];int arcs
[MVNum
][MVNum
];int vexnum
, arcnum
;
}AMGraph
;
int LocateVex(AMGraph G
, char v
)
{for (int i
= 0; i
< G
.vexnum
; i
++){if (G
.vexs
[i
] == v
){return i
;break;}}
}void CreatUDN(AMGraph
& G
)
{cout
<< "請輸入無向圖的總頂點數和邊數" << endl
;cout
<< "頂點數:"; cin
>> G
.vexnum
;while (1){cout
<< "邊數:"; cin
>> G
.arcnum
;if (G
.arcnum
> ((G
.vexnum
) * (G
.vexnum
- 1) / 2))cout
<< "邊數超出限制,請重新輸入邊數" << endl
;else break;}for (int i
= 0; i
< G
.vexnum
; i
++){cout
<< "第" << i
+ 1 << "個頂點的名稱: ";cin
>> G
.vexs
[i
];}for(int i
=0;i
<G
.vexnum
;i
++)for (int j
= 0; j
< G
.vexnum
; j
++){G
.arcs
[i
][j
] = MaxInt
;}cout
<< "請輸入每兩個頂點及其邊的權重" << endl
;for (int i
= 0; i
< G
.arcnum
; i
++){char v1
, v2
;int weight
; cout
<< "請輸入第" << i
+ 1 << "條邊及其兩個頂點的名稱( 形如(1 0 28)): ";cin
>> v1
>> v2
>> weight
;int index1
, index2
;index1
= LocateVex(G
, v1
); index2
= LocateVex(G
, v2
);G
.arcs
[index1
][index2
] = weight
;G
.arcs
[index2
][index1
] = G
.arcs
[index1
][index2
];}cout
<< "無向網構建完成......"<<endl
;}
void AMGraph_show(AMGraph G
)
{for (int i
= 0; i
< G
.vexnum
; i
++){for (int j
= 0; j
< G
.vexnum
; j
++){if (G
.arcs
[i
][j
] != MaxInt
) cout
<< G
.arcs
[i
][j
] << " ";else cout
<< "∞ ";}cout
<< endl
;}
}int main()
{AMGraph G
;CreatUDN(G
);AMGraph_show(G
);}
2、圖的各種遍歷算法實現 (返回目錄🖱)
以0結點為起點實現上述圖的深度優先和廣度優先遍歷算法;
#include <iostream>
using namespace std
;#define MaxInt 32767
#define MVNum 100
bool visited
[MVNum
];
typedef struct AMGraph
{char vexs
[MVNum
];int arcs
[MVNum
][MVNum
];int vexnum
, arcnum
;
}AMGraph
;
int LocateVex(AMGraph G
, char v
)
{for (int i
= 0; i
< G
.vexnum
; i
++){if (G
.vexs
[i
] == v
){return i
;break;}}
}void CreatUDN(AMGraph
& G
)
{cout
<< "請輸入無向圖的總頂點數和邊數" << endl
;cout
<< "頂點數:"; cin
>> G
.vexnum
;while (1){cout
<< "邊數:"; cin
>> G
.arcnum
;if (G
.arcnum
> ((G
.vexnum
) * (G
.vexnum
- 1) / 2))cout
<< "邊數超出限制,請重新輸入邊數" << endl
;else break;}for (int i
= 0; i
< G
.vexnum
; i
++){cout
<< "第" << i
+ 1 << "個頂點的名稱: ";cin
>> G
.vexs
[i
];}for (int i
= 0; i
< G
.vexnum
; i
++){visited
[i
] = 0;for (int j
= 0; j
< G
.vexnum
; j
++)G
.arcs
[i
][j
] = MaxInt
;}cout
<< "請輸入每兩個頂點及其邊的權重" << endl
;for (int i
= 0; i
< G
.arcnum
; i
++){char v1
, v2
;int weight
; cout
<< "請輸入第" << i
+ 1 <<"條邊及其兩個頂點的名稱( 形如(1 0 28)): ";cin
>> v1
>> v2
>> weight
;int index1
, index2
;index1
= LocateVex(G
, v1
); index2
= LocateVex(G
, v2
);G
.arcs
[index1
][index2
] = weight
;G
.arcs
[index2
][index1
] = G
.arcs
[index1
][index2
];}cout
<< "無向網構建完成......" << endl
;}
void AMGraph_show(AMGraph G
)
{for (int i
= 0; i
< G
.vexnum
; i
++){for (int j
= 0; j
< G
.vexnum
; j
++){if (G
.arcs
[i
][j
] != MaxInt
) cout
<< G
.arcs
[i
][j
] << " ";else cout
<< "∞ ";}cout
<< endl
;}
}
void DFS_AM(AMGraph
&G
, int v
)
{int i
;cout
<<G
.vexs
[v
]; visited
[v
] = true
; for ( i
= 0; i
< G
.vexnum
; i
++){if ((G
.arcs
[v
][i
] != MaxInt
) && !visited
[i
])DFS_AM(G
,i
);}
}
void DFSTraverse(AMGraph
&G
)
{int i
;for (i
= 0; i
< G
.vexnum
; ++i
)visited
[i
] = 0;for (i
= 0; i
< G
.vexnum
; ++i
){if (!visited
[i
])DFS_AM(G
, i
);}}int main()
{AMGraph G
;CreatUDN(G
);AMGraph_show(G
);char x
;cout
<< "請輸入遍歷開始的結點 ";cin
>> x
;DFSTraverse(G
);
}
3、最小生成樹的算法實現(返回目錄🖱)
利用普里姆(Prim)算法或克魯斯卡爾(Kruskal)算法求上圖的最小生成樹,算法實現代碼必須有注釋。
#include <iostream>
using namespace std
;#define MaxInt 32767
#define MVNum 100
bool visited
[MVNum
];
typedef struct AMGraph
{char vexs
[MVNum
];int arcs
[MVNum
][MVNum
];int vexnum
, arcnum
;
}AMGraph
;
int LocateVex(AMGraph G
, char v
)
{for (int i
= 0; i
< G
.vexnum
; i
++){if (G
.vexs
[i
] == v
){return i
;break;}}
}
void CreatUDN(AMGraph
& G
)
{cout
<< "請輸入無向圖的總頂點數和邊數" << endl
;cout
<< "頂點數:"; cin
>> G
.vexnum
;while (1){cout
<< "邊數:"; cin
>> G
.arcnum
;if (G
.arcnum
> ((G
.vexnum
) * (G
.vexnum
- 1) / 2))cout
<< "邊數超出限制,請重新輸入邊數" << endl
;else break;}for (int i
= 0; i
< G
.vexnum
; i
++){cout
<< "第" << i
+ 1 << "個頂點的名稱: ";cin
>> G
.vexs
[i
];}for (int i
= 0; i
< G
.vexnum
; i
++){visited
[i
] = 0;for (int j
= 0; j
< G
.vexnum
; j
++)G
.arcs
[i
][j
] = MaxInt
;}cout
<< "請輸入每兩個頂點及其邊的權重" << endl
;for (int i
= 0; i
< G
.arcnum
; i
++){char v1
, v2
;int weight
; cout
<< "請輸入第" << i
+ 1 << "條邊及其兩個頂點的名稱( 形如(1 0 28)): ";cin
>> v1
>> v2
>> weight
;int index1
, index2
;index1
= LocateVex(G
, v1
); index2
= LocateVex(G
, v2
);G
.arcs
[index1
][index2
] = weight
;G
.arcs
[index2
][index1
] = G
.arcs
[index1
][index2
];}cout
<< "無向網構建完成......" << endl
;
}
void AMGraph_show(AMGraph G
)
{for (int i
= 0; i
< G
.vexnum
; i
++){for (int j
= 0; j
< G
.vexnum
; j
++){if (G
.arcs
[i
][j
] != MaxInt
) cout
<< G
.arcs
[i
][j
] << " ";else cout
<< "∞ ";}cout
<< endl
;}
}
typedef struct
{int adjvex
;int lowcost
;
}closedge
[MVNum
];closedge theclose
;
int minimun(AMGraph G
, closedge c
)
{int min
= MaxInt
; int min_index
= -1; for (int i
= 0; i
< G
.vexnum
; i
++){if (c
[i
].lowcost
> 0 && c
[i
].lowcost
< min
){min
= c
[i
].lowcost
;min_index
= i
;}}return min_index
;
}
void MSTreePrim(AMGraph G
,char v
)
{int k
= LocateVex(G
,v
); for (int i
= 0; i
< G
.vexnum
; i
++){if (i
!= k
){theclose
[i
].adjvex
= k
;theclose
[i
].lowcost
= G
.arcs
[k
][i
];}}theclose
[k
].lowcost
= 0; for (int i
= 1; i
< G
.vexnum
; i
++){k
= minimun(G
, theclose
);cout
<< G
.vexs
[theclose
[k
].adjvex
] << G
.vexs
[k
] << endl
;theclose
[k
].lowcost
= 0;for (int i
= 0; i
< G
.vexnum
; i
++){if (G
.arcs
[k
][i
] < theclose
[i
].lowcost
){theclose
[i
].lowcost
= G
.arcs
[k
][i
];theclose
[i
].adjvex
= k
;}}}cout
<< "Prinm算法最小生成樹構建完成......";
}int main()
{AMGraph G
;CreatUDN(G
);AMGraph_show(G
); cout
<< "請輸入開始遍歷的頂點: ";char x
;cin
>> x
;MSTreePrim(G
, x
);
}
4、最短路徑的算法實現(返回目錄🖱)
利用狄克斯特拉(Dijkstra)算法求上圖中0結點到其它結點的最短路徑,算法實現代碼必須有注釋
#include <iostream>
using namespace std
;#define MaxInt 32767
#define MVNum 100
bool visited
[MVNum
];
typedef struct AMGraph
{char vexs
[MVNum
];int arcs
[MVNum
][MVNum
];int vexnum
, arcnum
;
}AMGraph
;
int LocateVex(AMGraph G
, char v
)
{for (int i
= 0; i
< G
.vexnum
; i
++){if (G
.vexs
[i
] == v
){return i
;break;}}
}
void CreatUDN(AMGraph
& G
)
{cout
<< "請輸入無向圖的總頂點數和邊數" << endl
;cout
<< "頂點數:"; cin
>> G
.vexnum
;while (1){cout
<< "邊數:"; cin
>> G
.arcnum
;if (G
.arcnum
> ((G
.vexnum
) * (G
.vexnum
- 1) / 2))cout
<< "邊數超出限制,請重新輸入邊數" << endl
;else break;}for (int i
= 0; i
< G
.vexnum
; i
++){cout
<< "第" << i
+ 1 << "個頂點的名稱: ";cin
>> G
.vexs
[i
];}for (int i
= 0; i
< G
.vexnum
; i
++){visited
[i
] = 0;for (int j
= 0; j
< G
.vexnum
; j
++)G
.arcs
[i
][j
] = MaxInt
;}cout
<< "請輸入每兩個頂點及其邊的權重" << endl
;for (int i
= 0; i
< G
.arcnum
; i
++){char v1
, v2
; int weight
; cout
<< "請輸入第" << i
+ 1 << "條邊及其兩個頂點的名稱( 形如(1 0 28)): ";cin
>> v1
>> v2
>> weight
;int index1
, index2
; index1
= LocateVex(G
, v1
); index2
= LocateVex(G
, v2
);G
.arcs
[index1
][index2
] = weight
;G
.arcs
[index2
][index1
] = G
.arcs
[index1
][index2
];}cout
<< "無向網構建完成......" << endl
;
}
void AMGraph_show(AMGraph G
)
{for (int i
= 0; i
< G
.vexnum
; i
++){for (int j
= 0; j
< G
.vexnum
; j
++){if (G
.arcs
[i
][j
] != MaxInt
) cout
<< G
.arcs
[i
][j
] << " ";else cout
<< "∞ ";}cout
<< endl
;}
}
int dist
[MVNum
];
int sign
[MVNum
];
int pre
[MVNum
]; void Dijkstra(AMGraph G
, int v
)
{for (int i
= 0; i
< G
.vexnum
; i
++){dist
[i
] = G
.arcs
[v
][i
];sign
[i
] = 0; if (dist
[i
] < MaxInt
) pre
[i
] = v
; else pre
[i
] = -1; }sign
[v
] = 1;for (int i
= 0; i
< G
.vexnum
-1; i
++){int min_v
; int min
= MaxInt
;for (int i
= 0; i
< G
.vexnum
; i
++){if (sign
[i
] == 0 && dist
[i
] < min
){min
= dist
[i
];min_v
= i
;}}sign
[min_v
] = 1; for (int i
= 0; i
< G
.vexnum
; i
++){if (sign
[i
] == 0 && dist
[i
] > dist
[min_v
] + G
.arcs
[min_v
][i
]){dist
[i
] = dist
[min_v
] + G
.arcs
[min_v
][i
];pre
[i
] = min_v
;}}}cout
<< "輸出頂點" << v
<< "到各頂點的最短路徑" << endl
<< "result:" << endl
;for (int i
= 0; i
< G
.vexnum
; i
++){cout
<< "<" << v
<< "," << i
<< "> : ";int p
= pre
[i
];if (p
!= -1){cout
<< " " << dist
[i
] << "\t";cout
<< i
;while (p
!= v
){cout
<< "<--" << p
;p
= pre
[p
]; }cout
<< "<--" << v
;}else cout
<< "∞"; cout
<< endl
;}
}int main()
{AMGraph G
;CreatUDN(G
);AMGraph_show(G
); Dijkstra(G
, 0);
}
四、實驗過程原始數據記錄
1.、圖的鄰接表和鄰接矩陣存儲
建立下圖的鄰接表或鄰接矩陣,并輸出之;
思路:通過構建鄰接矩陣來實現無向圖。
2、圖的各種遍歷算法實現
以0結點為起點實現上述圖的深度優先和廣度優先遍歷算法;
3、最小生成樹的算法實現
利用普里姆(Prim)算法或克魯斯卡爾(Kruskal)算法求上圖的最小生成樹,算法實現代碼必須有注釋。
4、最短路徑的算法實現
利用狄克斯特拉(Dijkstra)算法求上圖中0結點到其它結點的最短路徑,算法實現代碼必須有注釋。
五、實驗結果及分析
通過構造鄰接矩陣實現了圖的存儲、圖的深度優先遍歷算法、圖的最小生成樹Prim算法、最短路徑的Dijkstra算法,通過對這些算法的實現,讓我對圖有了更深的理解。
總結
以上是生活随笔為你收集整理的实验三 图的操作与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。