目录
原题复刻:
思想的火花:
1.
struct ArcNode //边结点
{
此结构体就是每一条链中非头节点储存的信息
int adjvex; // //该节点指向的对应顶点是谁,即回答自己是谁
struct ArcNode *nextarc; //指向链的下一条节点
OtherInfo info; //和边相关的信息,此题未用到
} ArcNode;
2.
struct VNode
{
VerTexType data; //顶点信息,也就是链的头结点
ArcNode *firstarc; //指向第一条依附该顶点的边的指针,也就是头结点指向的第一个节点
} VNode, AdjList[MVNum];
3.
struct Graph
{
AdjList vertices; //邻接表
int vexnum, arcnum; //图的当前顶点数和边数
} ;
4.
VerTexType Vertexdata(const Graph &g, int i)
{
return g.vertices[i].data;//得到顶点i的数据
}
5.
int LocateVex(const Graph &g, VerTexType v)
{
//确定顶点v在G中的位置
for(int i = 0; i < g.vexnum; ++i) if(g.vertices[i].data == v) return i;
return -1;
}
6.
int FirstAdjVex(const Graph &g, int v)
{
//返回顶点v的第一个邻接顶点。若顶点在G中没有邻接表顶点,则返回-1。
if(g.vertices[v].firstarc)return g.vertices[v].firstarc->adjvex;
return -1;
}
7.
int NextAdjVex(const Graph &g, int v, int w)
{
ArcNode *p1=g.vertices[v].firstarc;//找个指针p移动
while(p1->adjvex!=w)p1=p1->nextarc;//负责找到与顶点v有边的除节点w外的下一个节点
if(p1->nextarc)return p1->nextarc->adjvex;//if防止越界
return -1;
}
8.
void sort(ArcNode *arclist)
{//对每个顶点的链表排序,按顶点编号从小到大排列
ArcNode *p1,*p2;
for(p1=arclist; p1; p1=p1->nextarc)
{
for(p2=p1->nextarc; p2; p2=p2->nextarc)
{
if(p1->adjvex>p2->adjvex)swap(p1->adjvex,p2->adjvex);
}
}
//非常笨拙的排序方法,但数据很小,就没必要要求高效sort
}
9.
int CreateUDG(Graph &g)
{
//采用邻接表表示法,创建无向图G
cin>>g.vexnum>>g.arcnum;//顶点数,边数
for(int i=0; i<g.vexnum; i++)
{
cin>>g.vertices[i].data;//相当于邻接矩阵中的顶点表
g.vertices[i].firstarc=NULL;//在有边关系前,任何一个顶点都没有邻接点
}
while(g.arcnum--)
{
string v1,v2;
cin>>v1>>v2;
int h1=LocateVex(g,v1),h2=LocateVex(g,v2);//分别确定顶点v1与v2在G中vexnum个链的位置
if(h1!=-1&&h2!=-1)//if防止越界
{
//v1:
ArcNode*p1=new ArcNode;
p1->adjvex=h2;//顶点v1的邻接点是v2
//头插法:新的节点都会是头节点的新的第一个节点
p1->nextarc=g.vertices[h1].firstarc;
g.vertices[h1].firstarc=p1;
//v2:
ArcNode*p2=new ArcNode;//顶点v2的邻接点是v1
//头插法:新的节点都会是头节点的新的第一个节点
p2->adjvex=h1;
p2->nextarc=g.vertices[h2].firstarc;
g.vertices[h2].firstarc=p2;
}
}
/***********************************/
for(i = 0; i < g.vexnum; ++i)
{
sort(g.vertices[i].firstarc); 保证有序,不依赖输入次序
}//for
return OK;
}
代码复刻:
#include <iostream>
#include <iomanip>
using namespace std;
#define MVNum 100 //最大顶点数
#define OK 1
typedef string VerTexType; //顶点信息
typedef int OtherInfo; //和边相关的信息
//- - - - -图的邻接表存储表示- - - - -
typedef struct ArcNode //边结点
{
int adjvex; //该节点指向的对应顶点是谁,即回答自己是谁
struct ArcNode *nextarc; //指向下一条边的指针
OtherInfo info; //和边相关的信息
} ArcNode;
typedef struct VNode
{
VerTexType data; //顶点信息
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
} VNode, AdjList[MVNum]; //AdjList表示邻接表类型
typedef struct
{
AdjList vertices; //邻接表
int vexnum, arcnum; //图的当前顶点数和边数
} Graph;
//得到顶点i的数据
VerTexType Vertexdata(const Graph &g, int i)
{
return g.vertices[i].data;
}
int LocateVex(const Graph &g, VerTexType v)
{
//确定点v在G中的位置
for(int i = 0; i < g.vexnum; ++i)
if(g.vertices[i].data == v)
return i;
return -1;
}//LocateVex
//返回v的第一个邻接顶点。若顶点在G中没有邻接表顶点,则返回-1。
int FirstAdjVex(const Graph &g, int v)
{
/****在此下面完成代码***************/
if(g.vertices[v].firstarc)return g.vertices[v].firstarc->adjvex;
return -1;
/***********************************/
}
// 返回v的(相对于w的)下一个邻接顶点。
int NextAdjVex(const Graph &g, int v, int w)
{
/****在此下面完成代码***************/
ArcNode *p1=g.vertices[v].firstarc;
while(p1->adjvex!=w)p1=p1->nextarc;
if(p1->nextarc)return p1->nextarc->adjvex;
return -1;
/***********************************/
}
//对每个顶点的链表排序,按顶点编号从小到大排列
void sort(ArcNode *arclist)
{
/****在此下面完成代码***************/
ArcNode *p1,*p2;
for(p1=arclist; p1; p1=p1->nextarc)
{
for(p2=p1->nextarc; p2; p2=p2->nextarc)
{
if(p1->adjvex>p2->adjvex)swap(p1->adjvex,p2->adjvex);
}
}
/***********************************/
}
int CreateUDG(Graph &g)
{
//采用邻接表表示法,创建无向图G
/****在此下面完成代码***************/
cin>>g.vexnum>>g.arcnum;
for(int i=0; i<g.vexnum; i++)
{
cin>>g.vertices[i].data;
g.vertices[i].firstarc=NULL;
}
while(g.arcnum--)
{
string v1,v2;
cin>>v1>>v2;
int h1=LocateVex(g,v1),h2=LocateVex(g,v2);
if(h1!=-1&&h2!=-1)
{
ArcNode*p1=new ArcNode;
p1->adjvex=h2;
p1->nextarc=g.vertices[h1].firstarc;
g.vertices[h1].firstarc=p1;
ArcNode*p2=new ArcNode;
p2->adjvex=h1;
p2->nextarc=g.vertices[h2].firstarc;
g.vertices[h2].firstarc=p2;
}
}
/***********************************/
for(int i = 0; i < g.vexnum; ++i)
{
sort(g.vertices[i].firstarc); 保证有序,不依赖输入次序
}//for
return OK;
}//CreateUDG
void DestroyUDG(Graph &g)
{
//you should do this
}
int main()
{
Graph g;
CreateUDG(g);
//输出各个顶点的邻接点
for(int i = 0; i < g.vexnum; i++)
{
cout << Vertexdata(g, i) << ":";
for(int w = FirstAdjVex(g, i); w >= 0; w = NextAdjVex(g, i, w))
{
cout << ' ' << Vertexdata(g, w);
}
cout << endl;
}
DestroyUDG(g);
return 0;
}//main