数据结构C语言版 图的邻接表存储表示和实现文档格式.docx

上传人:b****6 文档编号:19691054 上传时间:2023-01-08 格式:DOCX 页数:22 大小:20.52KB
下载 相关 举报
数据结构C语言版 图的邻接表存储表示和实现文档格式.docx_第1页
第1页 / 共22页
数据结构C语言版 图的邻接表存储表示和实现文档格式.docx_第2页
第2页 / 共22页
数据结构C语言版 图的邻接表存储表示和实现文档格式.docx_第3页
第3页 / 共22页
数据结构C语言版 图的邻接表存储表示和实现文档格式.docx_第4页
第4页 / 共22页
数据结构C语言版 图的邻接表存储表示和实现文档格式.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

数据结构C语言版 图的邻接表存储表示和实现文档格式.docx

《数据结构C语言版 图的邻接表存储表示和实现文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构C语言版 图的邻接表存储表示和实现文档格式.docx(22页珍藏版)》请在冰豆网上搜索。

数据结构C语言版 图的邻接表存储表示和实现文档格式.docx

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1