1.鄰接表
鄰接鏈表表示有一個包含|V|條鏈表的數組Adj所構成,每個頂點有一條鏈表。對於每個頂點u,鄰接鏈表Adj[u]包含所有與頂點u之間有邊相連的頂點v。
儲存空間:O(V+E)。
無向圖:所有鄰接鏈表的長度之和為2|E|;有向圖:所有鄰接鏈表的長度之和為|E|。
優點
1.表示稀疏圖,表示緊湊,節約空間,表示簡單。
2.魯棒性高,可以對其進行簡單修改來支援許多其他的圖變種。
缺點
1.無法快速判斷兩個頂點u和v之間是否是圖中的一條邊,需要在鄰接鏈表Adj[u]裡搜尋結點v。
#define MAXVEX 10 // maximum vertex numbers in the graphtypedef int VertexType; // vertex data typetypedef int EdgeType; // edge weight type// edge node to record the adjacent vertex node for a vertex nodetypedef struct EdgeNode { int adjvex; // the adjacent vertex node position in array EdgeType weight; // edge weight struct EdgeNode* next; // next edge node}EdgeNode;// vertex node to record the data for a vertex nodetypedef struct VertexNode { VertexType data; // vertex data EdgeNode *firstedge; // first edge node pointer}VertexNode; // graphtypedef struct { VertexNode adj[MAXVEX]; int numVertexes; int numEdges;}Graph;Graph* CreateGraph(){ Graph* G = new Graph; cout << "input vertex num and edge num:" << endl; cin >> G->numVertexes >> G->numEdges; cout << "input vertex data one by one:" << endl; for (int index = 0; index < G->numVertexes; index++) { cin >> G->adj[index].data; G->adj[index].firstedge = NULL; } cout << "input edge each by two vertex index(begin from 0):" << endl; for (int index = 0; index < G->numEdges; index++) { int i, j; cin >> i >> j; EdgeNode* e = new EdgeNode; e->adjvex = j; e->next = G->adj[i].firstedge; G->adj[i].firstedge = e;#define NODRECTIONGRAPH#ifdef NODRECTIONGRAPH e= new EdgeNode; e->adjvex = i; e->next = G->adj[j].firstedge; G->adj[j].firstedge = e;#endif } return G;}void BFS(Graph* G) { memset(visit, 0, sizeof(visit[0]) * MAXVEX); queue<EdgeNode*> q; EdgeNode* temp; for (int index = 0; index < G->numVertexes; index++) { if (!visit[index]) { visit[index] = true; q.push(G->adj[index].firstedge); cout << " from vertex data: " << G->adj[index].data << endl; while (!q.empty()) { temp = q.front(); if (temp && !visit[temp->adjvex]) { cout << "get weight: " << temp->weight << " to " << temp->adjvex << endl; visit[temp->adjvex] = true; q.push(temp->next); } q.pop(); } } }}void DFS_VISIT(Graph* G, int index){ visit[index] = true; cout << "vertex data: " << G->adj[index].data << endl; EdgeNode* temp = G->adj[index].firstedge; while (temp) { if (!visit[temp->adjvex]) DFS_VISIT(G, temp->adjvex); temp = temp->next; }}void DFS(Graph* G){ memset(visit, 0, sizeof(visit[0]) * MAXVEX); for (int index_i = 0; index_i < G->numVertexes; index_i++) { if (!visit[index_i]) DFS_VISIT(G, index_i); }}
2.鄰接矩陣
由一個|V|x|V|的矩陣A = (aij)表示。aij = 1,若含有(i,j)邊;aij = 0,其他。
儲存空間:O(V^2)。
無向圖:鄰接矩陣為對稱矩陣,可以減少圖儲存空間一半需求。
優點
1.表示稠密圖。
2.可以快速判斷兩個頂點u和v之間是否是圖中的一條邊。
缺點
1.消耗非常大的儲存空間。
#define MAXVEX 10 // maximum vertex numbers in the graphtypedef int VertexType; // vertex data typetypedef int EdgeType; // edge weight type#define INFINITY 65535 // set as infinity value// graphtypedef struct { VertexType vertex[MAXVEX]; // vertex list EdgeType arc[MAXVEX][MAXVEX]; // adjacent matrix int numVertexes; int numEdges;}Graph;Graph* CreateGraph(){ Graph* G = new Graph; cout << "input vertex num and edge num:" << endl; cin >> G->numVertexes >> G->numEdges; cout << "input vertex data one by one:" << endl; for (int index = 0; index < G->numVertexes; index++) { cin >> G->vertex[index]; } // initial adjacent matrix for (int index_i = 0; index_i < G->numVertexes; index_i++) for (int index_j = 0; index_j < G->numVertexes; index_j++) G->arc[index_i][index_j] = INFINITY; cout << "input edge each by two vertex index and weight:" << endl; for (int index = 0; index < G->numEdges; index++) { int i, j, w; cin >> i >> j >> w; G->arc[i][j] = w;#define NODRECTIONGRAPH#ifdef NODRECTIONGRAPH G->arc[j][i] = w;#endif } return G;}void BFS(Graph* G) { memset(visit, 0, sizeof(visit[0]) * MAXVEX); queue<int> q; for (int index = 0; index < G->numVertexes; index++) { if (!visit[index]) { visit[index] = true; q.push(index); while (!q.empty()) { int index_i = q.front(); cout << " from vertex " << index_i << " data: " << G->vertex[index_i] << endl; for (int index_j = 0; index_j < G->numVertexes; index_j++) { if (G->arc[index_i][index_j] != INFINITY && !visit[index_j]) { visit[index_j] = true; cout << "get weight: " << G->arc[index_i][index_j] << " to " << index_j << endl; q.push(index_j); } } q.pop(); } } }}void DFS_VISIT(Graph* G, int index){ visit[index] = true; cout << "vertex data: " << G->vertex[index] << endl; for (int index_j = 0; index_j < G->numVertexes; index_j++) { if (G->arc[index][index_j] != INFINITY && !visit[index_j]) DFS_VISIT(G, index_j); }}void DFS(Graph* G){ memset(visit, 0, sizeof(visit[0]) * MAXVEX); for (int index_i = 0; index_i < G->numVertexes; index_i++) { if (!visit[index_i]) DFS_VISIT(G, index_i); }}