圖的表示最長用的兩種方法是:
1)、鄰接矩陣表示法
2)、鄰接表表示
下面是兩種構造圖的方法
1)鄰接矩陣:
- #include <iostream>
- #include <vector>
- using namespace std;
- //枚舉類型,圖的種類 DG:有向圖;WDG:帶權值的有向圖;
- //UDG: 無向圖;WUDG: 帶權值的無向圖
- enum GraphKind {DG, WDG, UDG, WUDG};
- //vertexType頂點類型,VRType:頂點之間的關係類型,InfoType:弧的信息類型
- template <typename VertexType, typename VRType, typename InfoType>
- class MGraph
- {
- public:
- MGraph(int vexNum, GraphKind __kind) : vexnum(vexNum), arcnum(0), kind(__kind)
- {
- //分配頂點向量數組
- vvec = new VertexType[vexnum];
- //動態分配二維數組, 注意二維數組的動態分配
- arcs = new ArcCell *[vexnum];
- for (int i = 0; i < vexnum; i++)
- {
- //爲每一行動態分配空間
- arcs[i] = new ArcCell[vexnum];
- }
- }
- void Create()
- {
- switch (kind)
- {
- case DG:
- {
- CreateDG(); //構造一個有向圖
- break;
- }
- case WDG:
- {
- CreateWDG(); //構造一個帶權有向圖
- break;
- }
- case UDG:
- {
- CreateUDG(); //構造一個無向圖
- break;
- }
- case WUDG:
- {
- CreateWUDG(); //構造一個帶權無向圖
- break;
- }
- default:
- return;
- }
- }
- //初始化頂點數組和鄰接矩陣
- void Init()
- {
- cout << "請輸入每個頂點的關鍵字:" << endl;
- VertexType val;
- for (int i = 0; i < vexnum; i++)
- {
- cin >> val;
- vvec[i] = val;
- }
- for (int i = 0; i < vexnum; i++)
- {
- ArcCell ac;
- ac.adj = 0;
- ac.info = NULL;
- for (int j = 0; j < vexnum; j++)
- {
- arcs[i][j] = ac;
- }
- }
- }
- //構造一個有向圖
- void CreateDG()
- {
- Init();
- int vhead, vtail;
- cout << "請依次輸入每條邊的開始頂點和結束頂點:" << endl;
- while (cin >> vhead >> vtail)
- {
- arcnum++;
- arcs[vhead][vtail].adj = 1;
- }
- }
- //構造一個帶權有向圖
- void CreateWDG()
- {
- Init();
- int vhead, vtail;
- InfoType w;
- cout << "請依次輸入每條邊的開始頂點和結束頂點和權值:" << endl;
- while (cin >> vhead >> vtail >> w)
- {
- arcnum++;
- arcs[vhead][vtail].adj = w;
- }
- }
- //構造一個無向圖
- void CreateUDG()
- {
- Init();
- int vhead, vtail;
- cout << "請依次輸入每條邊的開始頂點和結束頂點:" << endl;
- while (cin >> vhead >> vtail)
- {
- arcnum += 2;
- arcs[vhead][vtail].adj = 1;
- arcs[vtail][vhead].adj = 1;
- }
- }
- //構造一個帶權無向圖
- void CreateWUDG()
- {
- Init();
- int vhead, vtail;
- InfoType w;
- cout << "請依次輸入每條邊的開始頂點和結束頂點和權值:" << endl;
- while (cin >> vhead >> vtail >> w)
- {
- arcnum += 2;
- arcs[vhead][vtail].adj = w;
- arcs[vtail][vhead].adj = w;
- }
- }
- void displayGraph()
- {
- cout << "總共有" << vexnum << "個頂點,"
- << arcnum << "條邊" << endl;
- for (int i = 0; i < vexnum; i++)
- {
- cout << "第" << i+1 << "個頂點是:" << vvec[i]
- << "相鄰的邊有: ";
- for (int j = 0; j < vexnum; j++)
- {
- if (arcs[i][j].adj != 0)
- cout << vvec[j] << "(" << arcs[i][j].adj << ") ";
- }
- cout << endl;
- }
- }
- private:
- struct ArcCell
- {
- VRType adj; //頂點關係類型。對於無權圖,用1或0表示
- //表示相鄰與否;對帶權圖,爲權值類型
- InfoType info; //該弧相關的信息的指針
- };
- VertexType *vvec; //頂點向量
- ArcCell **arcs; //鄰接矩陣
- int vexnum; //圖的當前頂點個數
- int arcnum; //圖的弧數
- GraphKind kind; //圖的種類標誌
- };
- int main()
- {
- cout << "構造無向圖:" << endl;
- MGraph<char, int, int> udgGraph(8, UDG);
- udgGraph.Create();
- udgGraph.displayGraph();
- cout << "構造帶權無向圖:" << endl;
- MGraph<char, int, int> wudgGraph(9, WUDG);
- wudgGraph.Create();
- wudgGraph.displayGraph();
- cout << "構造有向圖:" << endl;
- MGraph<char, int, int> dgGraph(6, DG);
- udgGraph.Create();
- udgGraph.displayGraph();
- cout << "構造帶權有向圖:" << endl;
- MGraph<char, int, int> wdgGraph(6, WDG);
- wdgGraph.Create();
- wdgGraph.displayGraph();
- system("pause");
- return 0;
- }
2)鄰接鏈表
- #include <iostream>
- using namespace std;
- //枚舉類型,圖的種類 DG:有向圖;WDG:帶權值的有向圖;
- //UDG: 無向圖;WUDG: 帶權值的無向圖
- enum GraphKind {DG, WDG, UDG, WUDG};
- template<typename VertexType, typename InfoType>
- class ALGraph
- {
- public:
- ALGraph(int verNum, GraphKind _kind)
- : vexnum(verNum), arcnum(0), kind(_kind)
- {
- for (int i = 0; i < MAX_VERTEX_NUM; i++)
- vertices[i].firstarc = NULL;
- }
- //構造圖,進行選擇
- void Create()
- {
- switch (kind)
- {
- case DG:
- {
- CreateDG(); //構造一個有向圖
- break;
- }
- case WDG:
- {
- CreateWDG(); //構造一個帶權有向圖
- break;
- }
- case UDG:
- {
- CreateUDG(); //構造一個無向圖
- break;
- }
- case WUDG:
- {
- CreateWUDG(); //構造一個帶權無向圖
- break;
- }
- default:
- return;
- }
- }
- //打印鄰接鏈表
- void displayGraph()
- {
- for (int i = 0; i < vexnum; i++)
- {
- cout << "第" << i+1 << "個頂點是:" << vertices[i].data
- << " 鄰接表爲: ";
- ArcNode *arcNode = vertices[i].firstarc;
- while (arcNode != NULL)
- {
- cout << " -> " << vertices[arcNode->adjvex].data
- << "(" << arcNode->info << ")";
- arcNode = arcNode->nextarc;
- }
- cout << endl;
- }
- }
- private:
- //初始化鄰接鏈表的表頭數組
- void InitVertics()
- {
- cout << "請輸入每個頂點的關鍵字:" << endl;
- VertexType val;
- for (int i = 0; i < vexnum; i++)
- {
- cin >> val;
- vertices[i].data = val;
- }
- }
- //插入一個表結點
- void insertArc(int vHead, int vTail, InfoType w)
- {
- //構造一個表結點
- ArcNode *newArcNode = new ArcNode;
- newArcNode->adjvex = vTail;
- newArcNode->nextarc = NULL;
- newArcNode->info = w;
- //arcNode 是vertics[vHead]的鄰接表
- ArcNode *arcNode = vertices[vHead].firstarc;
- if (arcNode == NULL)
- vertices[vHead].firstarc = newArcNode;
- else
- {
- while (arcNode->nextarc != NULL)
- {
- arcNode = arcNode->nextarc;
- }
- arcNode->nextarc = newArcNode;
- }
- arcnum++;
- }
- //構造一個有向圖
- void CreateDG()
- {
- InitVertics();
- int vhead, vtail;
- cout << "請依次輸入每條邊的開始頂點和結束頂點:" << endl;
- while (cin >> vhead >> vtail)
- {
- insertArc(vhead, vtail, 0);
- }
- }
- //構造一個帶權有向圖
- void CreateWDG()
- {
- InitVertics();
- int vhead, vtail;
- InfoType w;
- cout << "請依次輸入每條邊的開始頂點和結束頂點和權值:" << endl;
- while (cin >> vhead >> vtail >> w)
- {
- insertArc(vhead, vtail, w);
- }
- }
- //構造一個無向圖
- void CreateUDG()
- {
- InitVertics();
- int vhead, vtail;
- cout << "請依次輸入每條邊的開始頂點和結束頂點:" << endl;
- while (cin >> vhead >> vtail)
- {
- insertArc(vhead, vtail, 0);
- insertArc(vtail, vhead, 0);
- }
- }
- //構造一個帶權無向圖
- void CreateWUDG()
- {
- InitVertics();
- int vhead, vtail;
- InfoType w;
- cout << "請依次輸入每條邊的開始頂點和結束頂點和權值:" << endl;
- while (cin >> vhead >> vtail >> w)
- {
- insertArc(vhead, vtail, w);
- insertArc(vtail, vhead, w);
- }
- }
- //const數據成員必須在構造函數裏初始化
- static const int MAX_VERTEX_NUM = 20; //最大頂點個數
- struct ArcNode //表結點
- {
- int adjvex; //該弧所指向的頂點的位置
- ArcNode *nextarc; //指向下一條弧的指針
- InfoType info; //該弧相關信息的指針
- };
- struct VNode //頭結點
- {
- VertexType data; //頂點信息
- ArcNode *firstarc; //指向第一條依附於該頂點的弧的指針
- };
- /*VNode AdjList[MAX_VERTEX_NUM];*/
- /* AdjList[MAX_VERTEX_NUM] vertices;*/
- VNode vertices[MAX_VERTEX_NUM];
- int vexnum; //圖的當前頂點數
- int arcnum; //圖的弧數
- GraphKind kind; //圖的種類
- };
- int main()
- {
- cout << "構造一個8個頂點的無向圖:" << endl;
- ALGraph<char, int> udgGraph(8, UDG);
- udgGraph.Create();
- udgGraph.displayGraph();
- cout << "構造一個9個頂點的帶權無向圖:" << endl;
- ALGraph<char, int> wudgGraph(9, WUDG);
- wudgGraph.Create();
- wudgGraph.displayGraph();
- cout << "構造一個6個頂點的有向圖:" << endl;
- ALGraph<char, int> dgGraph(6, DG);
- dgGraph.Create();
- dgGraph.displayGraph();
- cout << "構造一個9個頂點的帶權有向圖:" << endl;
- ALGraph<char, int> wdgGraph(9, WDG);
- wdgGraph.Create();
- wdgGraph.displayGraph();
- system("pause");
- return 0;
- }