以鄰接表作爲存儲結構,實現以下圖的基本操作:
1. 增加一個新頂點;
2. 增加一條新邊。
/*以鄰接表作爲存儲結構,實現以下圖的基本操作:
*/
#include<iostream>
using namespace std;
#define MVNum 100 //最大定點數
typedef struct ArcNode //邊結點
{
int adjvex; //該邊指向的頂點的位置
struct ArcNode *nextarc;//指向下一條邊的指針
}ArcNode;
typedef struct VNode //頂點信息
{
char data;
ArcNode *firstarc; //指向第一條依附該頂點的邊的指針
}VNode,AdjList[MVNum]; //AdjList表示鄰接表類型
typedef struct
{
AdjList vertices;
int vexnum, arcnum; //圖的當前頂點數和邊數
}ALGraph;
int LocateVex(ALGraph G, char v) //返回頂點在圖中的位置,即在G.verticesp[]數組中的下標
{
for (int i = 0; i < G.vexnum; i++){
if (G.vertices[i].data == v) return i;
}
}
//---------------------採用鄰接表表示法創建無向圖
void CreateUDG(ALGraph &G)
{//採用鄰接表表示法,創建無向圖G
char v1, v2;
int i, k, j;
ArcNode *p1, *p2;
cout << "輸入圖的總頂點數和總邊數:";
cin >> G.vexnum >> G.arcnum; //輸入總頂點數,總邊數
cout << "輸入頂點的值:";
for (i = 0; i < G.vexnum; ++i){ //輸入個點,構造表頭結點表
cin >> G.vertices[i].data; //輸入頂點值,類型爲char
G.vertices[i].firstarc = NULL; //初始化表頭結點的指針域爲NULL
}
for (k = 0; k < G.arcnum; ++k){
cout << "輸入一條邊依附的兩個點:";
cin >> v1 >> v2; //輸入一條邊依附的兩個頂點 0<=v1,v2<G.arcnum-1
i = LocateVex(G, v1); j = LocateVex(G, v2);
//確定v1和v2在G中位置,即頂點在G.vertices中的序號
p1 = new ArcNode; //生成一個新的邊結點*p1
p1->adjvex = j; //鄰接點序號爲j
p1->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = p1;
//將新結點*p1插入頂點vi的邊表頭部
p2 = new ArcNode; //生成另一個對稱的新的邊結點*p2
p2->adjvex = i; //鄰接點序號爲i
p2->nextarc = G.vertices[j].firstarc; G.vertices[j].firstarc = p2;
//將新結點*p2插入頂點vj的邊表頭部
}
}
int visited[MVNum]; //訪問標誌數組
///----------------深度優先搜索遍歷圖
void DFS_AL(ALGraph G, int v)
{//圖G爲鄰接表類型,從第v個頂點出發深度優先搜索遍歷圖G
int w;
ArcNode *p; //邊結點
cout << G.vertices[v].data << " "; visited[v] = 1; //訪問第v個頂點,並置訪問標誌數組相應分量值爲1
p = G.vertices[v].firstarc;
while (p != NULL)
{
w = p->adjvex; //表示w是v的鄰接點
if (!visited[w]) DFS_AL(G, w);//如果w未訪問,則遞歸調用DFS_AL
p = p->nextarc; //p指向下一個邊結點
}
}
//------------------------------插入結點函數------------
void Insert(ALGraph &G) //從無向圖G中插入點v
{
int i, j,v,n;
char v1;
ArcNode *p1, *p2; //邊結點
v = G.vexnum; //v表示新插入的點的位置,即G.vertices[]的下標
G.vexnum = G.vexnum + 1; //總頂點數+1
cout << endl << endl<<"輸入新頂點的值:";
cin >> G.vertices[v].data; //輸入新頂點的值
G.vertices[v].firstarc = NULL; //初始化表頭結點的指針域爲NULL
//-------------------
cout << "輸入新頂點的鄰接邊的數量:";
cin >> n;
G.arcnum = G.arcnum + n;
for (int m = 0; m < n; m++){
cout << "輸入另一個頂點與新點構造一條新邊:";
cin >> v1;
i = v; j = LocateVex(G, v1);
//確定v1在G中位置,即頂點在G.vertices中的序號
p1 = new ArcNode; //生成一個新的邊結點*p1
p1->adjvex = j; //鄰接點序號爲j
p1->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = p1;
//將新結點*p1插入頂點vi的邊表頭部
p2 = new ArcNode; //生成另一個對稱的新的邊結點*p2
p2->adjvex = i; //鄰接點序號爲i
p2->nextarc = G.vertices[j].firstarc; G.vertices[j].firstarc = p2;
cout << "插入完成"<<endl;
}
}
void InsertArc(ALGraph &G) //在無向圖中插入新邊
{
char v1, v2;
int i, j,n;
ArcNode *p1, *p2;
cout << "輸入插入的新邊的數量:";
cin >> n;
G.arcnum = G.arcnum + n;
for (int m = 0; m < n; m++){
cout << "輸入一條邊依附的兩個點:";
cin >> v1>>v2;
i = LocateVex(G, v1); j = LocateVex(G, v2);
//確定v1,v2在G中位置,即頂點在G.vertices中的序號
p1 = new ArcNode; //生成一個新的邊結點*p1
p1->adjvex = j; //鄰接點序號爲j
p1->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = p1;
//將新結點*p1插入頂點vi的邊表頭部
p2 = new ArcNode; //生成另一個對稱的新的邊結點*p2
p2->adjvex = i; //鄰接點序號爲i
p2->nextarc = G.vertices[j].firstarc; G.vertices[j].firstarc = p2;
cout << "插入完成" << endl;
}
}
int main()
{
ALGraph G;
char v;
int x;
CreateUDG (G);
cout << "無向圖G已經建立" << endl << "輸入遍歷的起始頂點:";
cin >> v;
cout << "深度優先搜索遍歷圖G可得頂點:";
for (int i = 0; i < G.vexnum; i++){ //重置是標誌數組的值爲0
visited[i] = 0;
}
DFS_AL(G, LocateVex(G,v));
cout <<endl;
for (int i = 0; i < 4; i++){ //方便操作
cout << endl << "------輸入對圖的操作-------" << endl << "1:插入新頂點 "
<< "2:插入新邊 " << "3:深度優先搜索遍歷圖G" << endl;
cin >> x;
switch (x)
{
case 1: Insert(G); break;
case 2: InsertArc(G); break;
case 3: {
for (int i = 0; i < G.vexnum; i++){ //重置標誌數組
visited[i] = 0;
}
cout << "輸入遍歷的起始頂點:";
cin >> v;
cout << "深度優先搜索遍歷圖G可得頂點:";
DFS_AL(G, LocateVex(G, v));
cout << endl; break; }
}
}
}