数据结构C语言版 图的邻接表存储表示和实现文档格式.docx
- 文档编号:19691054
- 上传时间:2023-01-08
- 格式:DOCX
- 页数:22
- 大小:20.52KB
数据结构C语言版 图的邻接表存储表示和实现文档格式.docx
《数据结构C语言版 图的邻接表存储表示和实现文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构C语言版 图的邻接表存储表示和实现文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
typedefintQElemType;
//队列类型
//单链队列--队列的链式存储结构
typedefstructQNode
QElemTypedata;
//数据域
structQNode*next;
//指针域
}QNode,*QueuePtr;
QueuePtrfront,//队头指针,指针域指向队头元素
rear;
//队尾指针,指向队尾元素
}LinkQueue;
//若G中存在顶点u,则返回该顶点在图中位置;
否则返回-1。
intLocateVex(ALGraphG,VertexTypeu)
inti;
for(i=0;
i<
G.vexnum;
++i)
if(strcmp(u,G.vertices[i].data)==0)
returni;
return-1;
}
//采用邻接表存储结构,构造没有相关信息的图G(用一个函数构造4种图)。
intCreateGraph(ALGraph*G)
inti,j,k;
intw;
//权值
VertexTypeva,vb;
ArcNode*p;
printf("
请输入图的类型(有向图:
0,有向网:
1,无向图:
2,无向网:
3):
"
);
scanf("
%d"
&
(*G).kind);
请输入图的顶点数和边数:
(空格)\n"
%d%d"
&
(*G).vexnum,&
(*G).arcnum);
请输入%d个顶点的值(<
%d个字符):
\n"
(*G).vexnum,MAX_NAME);
for(i=0;
i<
(*G).vexnum;
++i)//构造顶点向量
{
scanf("
%s"
(*G).vertices[i].data);
(*G).vertices[i].firstarc=NULL;
}
if((*G).kind==1||(*G).kind==3)//网
printf("
请顺序输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔):
else//图
请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔):
for(k=0;
k<
(*G).arcnum;
++k)//构造表结点链表
if((*G).kind==1||(*G).kind==3)//网
scanf("
%d%s%s"
w,va,vb);
else//图
%s%s"
va,vb);
i=LocateVex(*G,va);
//弧尾
j=LocateVex(*G,vb);
//弧头
p=(ArcNode*)malloc(sizeof(ArcNode));
p->
adjvex=j;
if((*G).kind==1||(*G).kind==3)//网
{
p->
info=(int*)malloc(sizeof(int));
*(p->
info)=w;
}
else
info=NULL;
//图
nextarc=(*G).vertices[i].firstarc;
//插在表头
(*G).vertices[i].firstarc=p;
if((*G).kind>
=2)//无向图或网,产生第二个表结点
p=(ArcNode*)malloc(sizeof(ArcNode));
adjvex=i;
if((*G).kind==3)//无向网
{
p->
info=(int*)malloc(sizeof(int));
*(p->
}
else
//无向图
nextarc=(*G).vertices[j].firstarc;
(*G).vertices[j].firstarc=p;
return1;
//销毁图G。
voidDestroyGraph(ALGraph*G)
ArcNode*p,*q;
i<
++i)
p=(*G).vertices[i].firstarc;
while(p)
q=p->
nextarc;
if((*G).kind%2)//网
free(p->
info);
free(p);
p=q;
(*G).vexnum=0;
(*G).arcnum=0;
//返回v的值。
VertexType*GetVex(ALGraphG,intv)
if(v>
=G.vexnum||v<
0)
exit(0);
return&
G.vertices[v].data;
//对v赋新值value。
intPutVex(ALGraph*G,VertexTypev,VertexTypevalue)
i=LocateVex(*G,v);
if(i>
-1)//v是G的顶点
strcpy((*G).vertices[i].data,value);
return1;
return0;
//返回v的第一个邻接顶点的序号。
若顶点在G中没有邻接顶点,则返回-1。
intFirstAdjVex(ALGraphG,VertexTypev)
intv1;
v1=LocateVex(G,v);
//v1为顶点v在图G中的序号
p=G.vertices[v1].firstarc;
if(p)
returnp->
adjvex;
else
return-1;
//返回v的(相对于w的)下一个邻接顶点的序号。
若w是v的最后一个
//邻接点,则返回-1。
intNextAdjVex(ALGraphG,VertexTypev,VertexTypew)
intv1,w1;
w1=LocateVex(G,w);
//w1为顶点w在图G中的序号
while(p&
&
p->
adjvex!
=w1)//指针p不空且所指表结点不是w
p=p->
if(!
p||!
nextarc)//没找到w或w是最后一个邻接点
else//p->
adjvex==w
//返回v的(相对于w的)下一个邻接顶点的序号
nextarc->
//在图G中增添新顶点v(不增添与顶点相关的弧,留待InsertArc()去做)。
voidInsertVex(ALGraph*G,VertexTypev)
{
strcpy((*G).vertices[(*G).vexnum].data,v);
//构造新顶点向量
(*G).vertices[(*G).vexnum].firstarc=NULL;
(*G).vexnum++;
//图G的顶点数加1
//删除G中顶点v及其相关的弧。
intDeleteVex(ALGraph*G,VertexTypev)
inti,j;
j=LocateVex(*G,v);
//j是顶点v的序号
if(j<
0)//v不是图G的顶点
return0;
p=(*G).vertices[j].firstarc;
//删除以v为出度的弧或边
while(p)
q=p;
if((*G).kind%2)//网
free(q->
free(q);
(*G).arcnum--;
//弧或边数减1
(*G).vexnum--;
//顶点数减1
for(i=j;
i++)//顶点v后面的顶点前移
(*G).vertices[i]=(*G).vertices[i+1];
//删除以v为入度的弧或边且必要时修改表结点的顶点位置值
i++)
//指向第1条弧或边
while(p)//有弧
if(p->
adjvex==j)//是以v为入度的边。
if(p==(*G).vertices[i].firstarc)//待删结点是第1个结点
{
(*G).vertices[i].firstarc=p->
if((*G).kind%2)//网
free(p->
free(p);
p=(*G).vertices[i].firstarc;
if((*G).kind<
2)//有向
(*G).arcnum--;
//弧或边数减1
}
else
q->
nextarc=p->
if((*G).kind%2)//网
p=q->
if(p->
adjvex>
j)
p->
adjvex--;
//修改表结点的顶点位置值(序号)
q=p;
p=p->
//在G中增添弧<
v,w>
若G是无向的,则还增添对称弧<
w,v>
。
intInsertArc(ALGraph*G,VertexTypev,VertexTypew)
intw1,i,j;
//弧尾或边的序号
j=LocateVex(*G,w);
//弧头或边的序号
if(i<
0||j<
0)
(*G).arcnum++;
//图G的弧或边的数目加1
if((*G).kind%2)//网
请输入弧(边)%s→%s的权值:
v,w);
w1);
p=(ArcNode*)malloc(sizeof(ArcNode));
p->
adjvex=j;
info=(int*)malloc(sizeof(int));
*(p->
info)=w1;
(*G).vertices[i].firstarc=p;
if((*G).kind>
=2)//无向,生成另一个表结点
if((*G).kind==3)//无向网
info)=w1;
info=NULL;
nextarc=(*G).vertices[j].firstarc;
(*G).vertices[j].firstarc=p;
//在G中删除弧<
若G是无向的,则还删除对称弧<
intDeleteArc(ALGraph*G,VertexTypev,VertexTypew)
i=LocateVex(*G,v);
//i是顶点v(弧尾)的序号
j=LocateVex(*G,w);
//j是顶点w(弧头)的序号
0||i==j)
p=(*G).vertices[i].firstarc;
//p指向顶点v的第一条出弧
adjvex!
=j)//p不空且所指之弧不是待删除弧<
{//p指向下一条弧
q=p;
p=p->
if(p&
adjvex==j)//找到弧<
if(p==(*G).vertices[i].firstarc)//p所指是第1条弧
(*G).vertices[i].firstarc=p->
//指向下一条弧
q->
nextarc=p->
if((*G).kind%2)//网
free(p->
free(p);
//释放此结点
if((*G).kind>
=2)//无向,删除对称弧<
p=(*G).vertices[j].firstarc;
//p指隙サ鉾的第一条出弧
while(p&
=i)//p不空且所指之弧不是待删除弧<
{//p指向下一条弧
q=p;
p=p->
if(p&
adjvex==i)//找到弧<
if(p==(*G).vertices[j].firstarc)//p所指是第1条弧
(*G).vertices[j].firstarc=p->
q->
if((*G).kind==3)//无向网
intvisited[MAX_VERTEX_NUM];
//访问标志数组(全局量)
void(*VisitFunc)(char*v);
//函数变量(全局量)
//算法7.5P169
//从第v个顶点出发递归地深度优先遍历图G。
voidDFS(ALGraphG,intv)
VertexTypev1,w1;
strcpy(v1,*GetVex(G,v));
visited[v]=1;
//设置访问标志为1(已访问)
VisitFunc(G.vertices[v].data);
//访问第v个顶点
for(w=FirstAdjVex(G,v1);
w>
=0;
w=NextAdjVex(G,v1,strcpy(w1,*GetVex(G,w))))
if(!
visited[w])
DFS(G,w);
//对v的尚未访问的邻接点w递归调用DFS
//算法7.4P169
//对图G作深度优先遍历。
voidDFSTraverse(ALGraphG,void(*Visit)(char*))
intv;
//使用全局变量VisitFunc,使DFS不必设函数指针参数
VisitFunc=Visit;
for(v=0;
v<
G.vexnum;
v++)
visited[v]=0;
//访问标志数组初始化
visited[v])
DFS(G,v);
//对尚未访问的顶点调用DFS
//构造一个空队列Q。
intInitQueue(LinkQueue*Q)
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));
//动态分配一个空间
(*Q).front)
(*Q).front->
next=NULL;
//队头指针指向空,无数据域,这样构成了一个空队列
//插入元素e为Q的新的队尾元素。
intEnQueue(LinkQueue*Q,QElemTypee)
QueuePtrp=(QueuePtr)malloc(sizeof(QNode));
if(!
p)//存储分配失败
//生成一个以为e为数据域的队列元素
data=e;
//将该新队列元素接在队尾的后面
(*Q).rear->
next=p;
(*Q).rear=p;
//若队列不空,删除Q的队头元素,用e返回其值,并返回1,否则返回0。
intDeQueue(LinkQueue*Q,QElemType*e)
QueuePtrp;
if((*Q).front==(*Q).rear)
p=(*Q).front->
next;
//队头元素
*e=p->
data;
next=p->
if((*Q).rear==p)
(*Q).rear=(*Q).front;
free(p);
//若Q为空队列,则返回1,否则返回0。
intQueueEmpty(LinkQueueQ)
if(Q.front==Q.rear)
//算法7.6P170
//按广度优先非递归遍历图G。
使用辅助队列Q和访问标志数组visited。
voidBFSTraverse(ALGraphG,void(*Visit)(char*))
intv,u,w;
VertexTypeu1,w1;
LinkQueueQ;
++v)
visited[v]=0;
//置初值
InitQueue(&
Q);
//置空的辅助队列Q
v++)//如果是连通图,只v=0就遍历全图
visited[v])//v尚未访问
visited[v]=1;
Visit(G.vertices[v].data);
EnQueue(&
Q,v);
//v入队列
while(!
QueueEmpty(Q))//队列不空
DeQueue(&
Q,&
u);
//队头元素出队并置为u
strcpy(u1,*GetVex(G,u));
for(w=FirstAdjVex(G,u1);
w=NextAdjVex(G,
u1,strcpy(w1,*GetVex(G,w))))
if(!
visited[w])//w为u的尚未访问的邻接顶点
{
visited
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构C语言版 图的邻接表存储表示和实现 数据结构 语言版 邻接 存储 表示 实现