關於圖的介紹網上很多,這裏就不介紹了,直接上代碼:
最小生成樹算法可以看看:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html
#include <iostream>
#include <iomanip>
#include <climits>
#include <queue>
using namespace std;
#define MAX_VERTEX_NUM 20 // 頂點數量上限
typedef char VerType; // 頂點結構 , 頂點的字母名稱
typedef int ArcType; // 邊的結構 , 權值
typedef enum {DG, UDG} GKind; // 圖類型,{有向圖,無向圖}
// 圖的存儲結構
typedef struct
{
int verNum, arcNum; // 頂點數量, 邊數量
GKind kind; // 圖類型
VerType vertex[MAX_VERTEX_NUM]; //頂點
ArcType arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邊
}Graph;
void CreateGraphByArray(Graph &G); // 創建圖G (通過預定義的數組)
void CreateGraph(Graph &G); // 創建圖G (通過輸入)
int VertexLoc(const Graph &G, const VerType &v); // 獲取頂點v在圖G中的位置
void PrintGraphArcs(const Graph &G); // 輸出圖G鄰接矩陣
void DFS(const Graph G, int vi, bool visited[]); // 圖G的深度優先遍歷的準備
void DFS_Traverse(const Graph &G); // 圖G的深度優先遍歷
void BFS_Traverse(const Graph &G); // 圖G的廣度優先遍歷
void MinSpanTree_Prim(const Graph &G); // 輸出圖G最小生成樹 (Prim算法)
void MinSpanTree_Kruskal(const Graph &G); // 輸出圖G最小生成樹 (kruskal算法)
int main()
{
Graph G;
//CreateGraph(G);
CreateGraphByArray(G);
cout << "圖的鄰接矩陣: " << endl;
PrintGraphArcs(G);
cout << "圖的深度優先遍歷:";
DFS_Traverse(G);
cout << endl;
cout << "圖的廣度優先遍歷:";
BFS_Traverse(G);
cout << endl;
cout << "最小生成樹:(prim算法)" << endl;
MinSpanTree_Prim(G);
cout << endl;
cout << "最小生成樹:(kruskal算法)" << endl;
MinSpanTree_Kruskal(G);
cout << endl;
return 0;
}
void CreateGraphByArray(Graph &G)
{
//數據例子取自課本Page168
G.kind = UDG;
const int vn = 6;
VerType V[vn + 1] = {"ABCDEF"};
const int en = 10;
VerType V1[en + 1] = {"ADFEBADFEB"};
VerType V2[en + 1] = {"CCCCCDFEBA"};
ArcType E[en] = {1,5,4,6,5,5,2,6,3,6};
// 輸入頂點
G.verNum = vn;
for(int i = 0; i < G.verNum; ++ i){
G.vertex[i] = V[i];
}
// 初始化鄰接矩陣
for(int vi = 0; vi < G.verNum; ++ vi){
for(int vj = 0; vj < G.verNum; ++ vj){
G.arcs[vi][vj] = INT_MAX;
}
}
// 輸入邊
G.arcNum = en;
for(int i = 0; i < G.arcNum; ++ i){
VerType &v1 = V1[i], &v2 = V2[i];
ArcType &e = E[i];
int vi = VertexLoc(G, v1), vj = VertexLoc(G, v2);
if(vi == G.verNum || vj == G.verNum){
continue;
}
if(UDG == G.kind){
G.arcs[vi][vj] = G.arcs[vj][vi] = e;
}else{
G.arcs[vi][vj] = e;
}
}
}
void CreateGraph(Graph &G)
{
// 輸入圖類型
int k;
cin >> k;
if(k == 0){
G.kind = DG;
}else{
G.kind = UDG;
}
// 輸入頂點
cin >> G.verNum;
for(int i = 0; i < G.verNum; ++ i){
cin >> G.vertex[i];
}
// 初始化鄰接矩陣
for(int vi = 0; vi < G.verNum; ++ vi){
for(int vj = 0; vj < G.verNum; ++ vj){
G.arcs[vi][vj] = INT_MAX;
}
}
// 輸入邊
VerType v1, v2; ArcType e;
cin >> G.arcNum;
for(int i = 0; i < G.arcNum; ++ i){
cin >> v1 >> v2 >> e;
int vi = VertexLoc(G, v1), vj = VertexLoc(G, v2);
if(vi == G.verNum || vj == G.verNum){
continue;
}
if(UDG == G.kind){
G.arcs[vi][vj] = G.arcs[vj][vi] = e;
}else{
G.arcs[vi][vj] = e;
}
}
}
int VertexLoc(const Graph &G, const VerType &v)
{
for(int i = 0; i < G.verNum; ++ i){
if(G.vertex[i] == v){
return i;
}
}
return G.verNum;
}
void PrintGraphArcs(const Graph &G)
{
for(int vi = 0; vi < G.verNum; ++ vi){
for(int vj = 0; vj < G.verNum; ++ vj){
if(G.arcs[vi][vj] == INT_MAX){
cout << setw(5) << "INF";
}else{
cout << setw(5) << G.arcs[vi][vj];
}
}
cout << endl;
}
}
void DFS(const Graph G, int vi, bool visited[])
{
cout << G.vertex[vi] << " ";
visited[vi] = true;
for(int vj = 0; vj < G.verNum; ++ vj){
if(G.arcs[vi][vj] != INT_MAX && !visited[vj]){
DFS(G, vj, visited);
}
}
}
void DFS_Traverse(const Graph &G)
{
bool visited[G.verNum];
for(int vi = 0; vi < G.verNum; ++ vi){
visited[vi] = false;
}
for(int vi = 0; vi < G.verNum; ++ vi){
if(!visited[vi]){
DFS(G, vi, visited);
}
}
}
void BFS_Traverse(const Graph &G)
{
bool visited[G.verNum];
for(int i = 0; i < G.verNum; ++ i){
visited[i] = false;
}
for(int i = 0; i < G.verNum; ++ i){
if(!visited[i]){
queue<int> que;
que.push(i);
visited[i] = true;
while(!que.empty()){
int vi = que.front();
cout << G.vertex[vi] << " ";
for(int vj = 0; vj < G.verNum; ++ vj){
if(G.arcs[vi][vj] != INT_MAX && !visited[vj]){
que.push(vj);
visited[vj] = true;
}
}
que.pop();
}
}
}
}
void MinSpanTree_Prim(const Graph &G)
{
//輔助結構, closeedge[i]={j, w}表示頂點vi權值最小的邊,vj爲邊頂點, w爲權值
struct
{
int adjvex; // 最小邊頂點
ArcType lowcost; // 最小邊上的權值
}closedge[G.verNum];
int k = 0;
for(int j = 0; j < G.verNum; ++ j){
if(j != k){
closedge[j] = {k, G.arcs[k][j]};
}
}
closedge[k].lowcost = 0; //表示頂點已經被選入Enew
for(int i = 1; i < G.verNum; ++ i){
/* 從Vnew選取權值最小的邊 */
k = -1;
for(int j = 0; j < G.verNum; ++ j){
if(closedge[j].lowcost != 0){
if(k == -1){
k = j;
}else if(closedge[j].lowcost < closedge[k].lowcost){
k = j;
}
}
}
int v0 = k, u0 = closedge[k].adjvex;
cout << G.vertex[u0] << " - " << G.vertex[v0] << endl; //輸出邊
closedge[k].lowcost = 0; //將該頂點選入Enew
/* 更新與新頂點相連的頂點最小權值 */
for(int j = 0; j < G.verNum; ++ j){
if(G.arcs[k][j] < closedge[j].lowcost){
closedge[j] = {k, G.arcs[k][j]};
}
}
}
}
void MinSpanTree_Kruskal(const Graph &G)
{
//輔助數組 (kruskal算法)
struct
{
int head; // 邊的起點
int tail; // 邊的終點
ArcType lowcost; // 邊上的權值
}edge[G.arcNum], temp;
//初始化edge
if(UDG == G.kind){
for(int i = 0, vi = 0; vi < G.verNum; ++ vi){
for(int vj = 0; vj < vi; ++ vj){
if(G.arcs[vi][vj] != INT_MAX){
edge[i].head = vi;
edge[i].tail = vj;
edge[i ++].lowcost = G.arcs[vi][vj];
}
}
}
}else{
for(int i = 0, vi = 0; vi < G.verNum; ++ vi){
for(int vj = 0; vj < G.verNum; ++ vj){
if(G.arcs[vi][vj] != INT_MAX){
edge[i].head = vi;
edge[i].tail = vj;
edge[i ++].lowcost = G.arcs[vi][vj];
}
}
}
}
//並根據權值從小到大排序
for(int i = 1; i <= G.arcNum; ++ i){
for(int j = 0; j < G.arcNum - i; ++ j){
if(edge[j].lowcost > edge[j + 1].lowcost){
temp = edge[j];
edge[j] = edge[j + 1];
edge[j + 1] = temp;
}
}
}
int vexset[G.verNum];
for(int i = 0; i < G.verNum; ++ i){
vexset[i] = i;
}
for(int i = 0; i < G.arcNum; ++ i){
int vi = edge[i].head, vj = edge[i].tail;
int vs1 = vexset[vi], vs2 = vexset[vj];
if(vs1 != vs2){
cout << G.vertex[vi] << " - " << G.vertex[vj] << endl;
for(int j = 0; j < G.verNum; ++ j){
if(vexset[j] == vs2){
vexset[j] = vs1;
}
}
}
}
}
對於這個圖:
最小生成樹的圖形爲:
所運行的結果如下: