以邻接表作为存储结构,实现以下图的基本操作:
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; }
}
}
}