构造图采用的是邻接表的方法,然后采用深度和广度优先进行遍历。(博主第一次写构造方法的时候花了很久写的很冗杂,虽然也实现了,但是感觉到处都在打补丁,拼拼凑凑写出来的,后来用了一分钟重写了一个,秒通过!!!欲哭无泪啊~原因主要是因为不同的输入格式导致的,以后些其他代码的时候要慎重考虑输入的格式问题)
下面贴代码!
根据书上的伪代码,写出定义的结构
const int MAX_VERTEX_NUM = 20;
bool visited[MAX_VERTEX_NUM]; //遍历访问标志
typedef struct ArcNode{
int adjvex; //该弧所指向的顶点的位置
struct ArcNode *nextarc; //指向下一条弧(边)的指针
int weight; //该弧(边)的权值
}ArcNode;
typedef struct VNode{
char data; //顶点信息
ArcNode *firstarc; //指向第一条依附该顶点的弧(边)的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct{
AdjList vertices;
int vexnum, arcnum; //图的当前顶点数和弧(边)数
int kind;
}ALGraph;
根据书上的伪代码,写出三个要用到的方法
//返回顶点v在图G中的位置
int LocateVex(ALGraph G, char v)
{
for (int i = 0; i < G.vexnum; i++){
if (v == G.vertices[i].data)
return i;
}
return -1;
}
//返回v的第一个邻接顶点
int FirstAdjVex(ALGraph G, int v)
{
if (G.vertices[v].firstarc)
return G.vertices[v].firstarc->adjvex;
return -1;
}
//返回顶点v相对于邻接点w的下一个邻接点
int NextAdjVex(ALGraph G, int v, int w)
{
ArcNode *p;
p = G.vertices[v].firstarc;
if (p){
while (p){
if (w == p->adjvex){
if (nullptr == p->nextarc)
return -1;
else
return p->nextarc->adjvex;
}
p = p->nextarc;
}
}
return -1;
}
下面是本体,一分钟改写出的构造图的方法!
//采用邻接表构造图G
void CreateGraph(ALGraph &G)
{
int i, j, weight;
char v, v1, v2;
ArcNode *p, *q = nullptr;
cout << "请输入图类型的序号:\n1.DG(有向图)\n2.DN(有向网\n3.UDG(无向图)\n4.UDN(无向网)" << endl;
cin >> G.kind;
cout << "请输入图G的顶点数和弧(边)数:";
cin >> G.vexnum >> G.arcnum;
//构造邻接表
for (i = 0; i < G.vexnum; i++){
cout << "请输入顶点vex[" << i << "]的值:";
cin >> G.vertices[i].data;
G.vertices[i].firstarc = nullptr;
}
cout << endl;
for (j = 0; j < G.arcnum; j++){
cout << "请输入第" << j << "条弧(边)的两个端点:";
cin >> v1 >> v2;
q = G.vertices[LocateVex(G, v1)].firstarc;
p = new ArcNode;
p->adjvex = LocateVex(G, v2);
p->nextarc = nullptr;
if (1 == G.kind || 3 == G.kind)
p->weight = 1;
else{
cout << "请输入该弧(边)的权值:";
cin >> weight;
p->weight = weight;
}
if (q){
while (q->nextarc)
q = q->nextarc;
q->nextarc = p;
}
else
G.vertices[LocateVex(G, v1)].firstarc = p;
if (3 == G.kind || 4 == G.kind){
q = G.vertices[LocateVex(G, v2)].firstarc;
p = new ArcNode;
p->adjvex = LocateVex(G, v1);
p->nextarc = nullptr;
if (1 == G.kind || 3 == G.kind)
p->weight = 1;
else{
p->weight = weight;
}
if (q){
while (q->nextarc)
q = q->nextarc;
q->nextarc = p;
}
else
G.vertices[LocateVex(G, v2)].firstarc = p;
}
}
}
根据书上的伪代码,写出深度优先遍历的递归方法
//深度优先遍历(递归)
void DFS(ALGraph G, int v)
{
visited[v] = true;
cout << G.vertices[v].data << " ";
for (int i = FirstAdjVex(G, v); i >= 0; i = NextAdjVex(G, v, i)){
if (!visited[i])
DFS(G, i);
}
}
void DFSTraverse(ALGraph G)
{
int i;
cout << "深度优先结果:" << endl;
for (i = 0; i < G.vexnum; i++)
visited[i] = false;
for (i = 0; i < G.vexnum; i++){
if (!visited[i])
DFS(G, i);
}
cout << endl;
}
打印函数在测试的时候不可少
//打印邻接表
void PrintALGraph(ALGraph G)
{
ArcNode *p;
for (int i = 0; i < G.vexnum; i++){
cout << G.vertices[i].data;
if (G.vertices[i].firstarc){
p = G.vertices[i].firstarc;
while (p){
if (3 == G.kind || 4 == G.kind)
cout << " - " << G.vertices[p->adjvex].data;
else
cout << "→" << G.vertices[p->adjvex].data;
p = p->nextarc;
}
}
cout << endl;
}
}
最后配上主函数
int main()
{
ALGraph graph;
CreateGraph(graph);
PrintALGraph(graph);
DFSTraverse(graph);
system("pause");
return 0;
}