数据结构 图操作.docx
《数据结构 图操作.docx》由会员分享,可在线阅读,更多相关《数据结构 图操作.docx(20页珍藏版)》请在冰豆网上搜索。
数据结构图操作
数据结构
实
验
指
导
书
实验四图
实验时数:
4学时
一:
实验目的:
(1)掌握图的存储思想及其存储实现。
(2)掌握图的深度、广度优先遍历算法思想及其程序实现。
(3)掌握图的常见应用算法的思想及其程序实现。
(4)理解有向无环图、最短路径等算法
二:
实验内容:
以下实验内容,1和2为必做内容,3为选做内容。
1.有向图
(1)键盘输入数据,建立一个有向图的邻接表,并输出该邻接表。
(2)在有向图的邻接表的基础上计算各顶点的度,并输出。
(3)以有向图的邻接表为基础实现并输出它的拓扑排序序列。
(4)在主函数中设计一个简单的菜单,分别调试上述算法。
#include
#include
#defineMAX_VERTEX_NUM8
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
#defineVertexTypeint
typedefintSElemType;
//***********************图*******************************
typedefstructArcNode//弧结点的结构
{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指向下一条弧的指针
intweight;//与弧相关的权值,无权则为0
}ArcNode;
typedefstructVNode//顶点结点的结构
{
intdegree,indegree;//顶点的度,入度
VertexTypedata;
ArcNode*firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;//顶点的实际数,边的实际数
}ALGraph;
intLocateVex(ALGraph&G,VertexTypeu)
{
inti;
for(i=0;i{
if(u==G.vertices[i].data)
returni;
}
return-1;
}
voidCreateDG(ALGraph&G)
{
VertexTypev1,v2;
inti,j;
ArcNode*p;
printf("\ninputthegrah'svexnumandarcnum:
");
scanf("%d%d",&G.vexnum,&G.arcnum);
printf("\ninputvertectdatas:
");
for(i=0;i{
scanf("%d",&G.vertices[i].data);
G.vertices[i].firstarc=NULL;
}
for(intk=0;k{
printf("\ninput%dtharc'sfirstarcnextarc:
\n",k+1);
scanf("%d%d",&v1,&v2);
i=LocateVex(G,v1);
j=LocateVex(G,v2);//head
if(i<0||j<0)
{
printf("\nERROR!
\n");
exit(0);
}
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=j;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
p->weight=0;
}
for(i=0;i{
printf("%d%d",i,G.vertices[i].data);
p=G.vertices[i].firstarc;
while(p)
{
printf("-->%d",p->adjvex);
p=p->nextarc;
}
printf("\n");
}
}
intGraphExit(ALGraphG,inti,intj)
{
ArcNode*p;
p=G.vertices[i].firstarc;
while(p&&p->adjvex!
=j)
p=p->nextarc;
if(p)return1;
elsereturn0;
}
voidDegree(ALGraph&G,inti)
{
intj;
ArcNode*p;
p=G.vertices[i].firstarc;
G.vertices[i].indegree=0;
G.vertices[i].degree=0;
for(j=0;jif(GraphExit(G,j,i))
{
G.vertices[i].indegree++;
G.vertices[i].degree++;
}
while(p!
=NULL)
{
G.vertices[i].degree++;
p=p->nextarc;
}
printf("\n%d'sindegree:
%d,degree:
%d",G.vertices[i].data,G.vertices[i].indegree,G.vertices[i].degree);
}
voidDe_Ingree(ALGraph&G)
{
inti,n,m;
for(i=0;i{
Degree(G,i);
}
}
//***********************栈*******************************
typedefstruct
{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
voidInitStack(SqStack&S)
{
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
S.base)
{
printf("\nfailtoallocatestorage!
");
exit(0);
}
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
printf("\nstoragewasallocatedsuccessfully!
\n");
}
voidGetTop(SqStackS,SElemType&e)
{
if(S.base==S.top)
printf("\nit'sanemptystack!
");
e=*(S.top-1);
}
intPush(SqStack&S,SElemTypee)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.base)
exit(0);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return1;
}
voidPop(SqStack&S,SElemType&e)
{
if(S.top==S.base)
printf("\nit'sanemptystack!
\n");
e=*--S.top;
}
intStackEmpty(SqStack&S)
{
if(S.top==S.base)
return1;
return0;
}
intDestroyStack(SqStackS)
{
S.top=NULL;
S.base=NULL;
delete[]S.base;
S.stacksize=0;
return1;
}
//*********************graph&stack*****************
intTopologicalSort(ALGraphG)
{
SqStackS;
ArcNode*p;
inti,k,j;
InitStack(S);
for(i=0;iif(G.vertices[i].indegree==0)
Push(S,i);
intcount=0;
while(!
StackEmpty(S))
{
Pop(S,i);
printf("%d",G.vertices[i].data);
++count;
j=LocateVex(G,G.vertices[i].data);
for(p=G.vertices[j].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
G.vertices[k].indegree--;
if(G.vertices[k].indegree==0)
Push(S,k);
}
}
if(count{
printf("\ntherisaloopinthisgraph!
\n");
return0;
}
else
{
printf("\nit'stopologicalsortshowedover!
\n");
return1;
}
DestroyStack(S);
}
intmain()
{
ALGraphG;
CreateDG(G);
De_Ingree(G);
TopologicalSort(G);
return0;
}
2.无向图
(1)建立一个无向图的邻接表,并输出该邻接表。
(2)采用邻接表存储实现无向图的深度优先遍历。
。
(3)采用邻接表存储实现无向图的广度优先遍历。
(4)在主函数中设计一个简单的菜单,分别调试上述算法。
#include
#include
#defineMAX_VERTEX_NUM8
#defineVertexTypeint
typedefintQElemType;
#defineMAXSIZE100
typedefstructArcNode//弧结点的结构
{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指向下一条弧的指针
intweight;//与弧相关的权值,无权则为0
}ArcNode;
typedefstructVNode//顶点结点的结构
{
intdegree,indegree;//顶点的度,入度
VertexTypedata;
ArcNode*firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;//顶点的实际数,边的实际数
}ALGraph;
//****************队列操作*******************************
typedefstruct
{
QElemType*base;
intfront;
intrear;
}SqQueue;
intInitQueue(SqQueue&Q)
{
Q.base=(QElemType*)malloc(MAXSIZE*sizeof(QElemType));
if(!
Q.base)
{
printf("\nfailtoallocstorage!
\n");
exit(0);
}
Q.front=Q.rear=0;
return1;
}
intEnQueue(SqQueue&Q,QElemTypee)
{
if((Q.rear+1)%MAXSIZE==Q.front)
{
printf("\nthequeueisfull!
\n");
exit(0);
}
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXSIZE;
return1;
}
intDeQueue(SqQueue&Q,QElemType&e)
{
if(Q.front==Q.rear)
{
printf("\nit'sanemptyqueue!
\n");
exit(0);
}
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXSIZE;
return1;
}
boolQueueEmpty(SqQueueQ)
{
if(Q.rear==Q.front)
return1;
elsereturn0;
}
//****************无向图*******************************
intLocateVex(ALGraph&G,VertexTypeu)
{
inti=0;
while((i=u))
i++;
if(ireturni;
else
return-1;
}
voidCreateUDG(ALGraph&G)
{
VertexTypev1,v2;
inti,j;
ArcNode*p,*s;
printf("\ninputthegrah'svexnumandarcnum:
");
scanf("%d%d",&G.vexnum,&G.arcnum);
printf("\ninputvertectdatas:
");
for(i=0;i{
scanf("%d",&G.vertices[i].data);
G.vertices[i].firstarc=NULL;
}
for(intk=0;k{
printf("\ninput%dtharc'stwodata'numbers:
\n",k+1);
scanf("%d%d",&v1,&v2);
i=LocateVex(G,v1);
j=LocateVex(G,v2);//head
if(i<0||j<0)
{
printf("\nERROR!
\n");
exit(0);
}
p=(ArcNode*)malloc(sizeof(ArcNode));
s=(ArcNode*)malloc(sizeof(ArcNode));
s->adjvex=j;
s->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=s;
p->adjvex=i;
p->nextarc=G.vertices[j].firstarc;
G.vertices[j].firstarc=p;
}
for(i=0;i{
printf("%d%d",i,G.vertices[i].data);
p=G.vertices[i].firstarc;
while(p)
{
printf("--%d",p->adjvex);
p=p->nextarc;
}
printf("\n");
}
}
intGraphExit(ALGraphG,inti,intj)
{
ArcNode*p;
p=G.vertices[i].firstarc;
while(p&&p->adjvex!
=j)
p=p->nextarc;
if(p)return1;
elsereturn0;
}
voidDegree(ALGraph&G,inti)
{
intj;
ArcNode*p;
p=G.vertices[i].firstarc;
G.vertices[i].indegree=0;
G.vertices[i].degree=0;
for(j=0;jif(GraphExit(G,j,i))
{
G.vertices[i].indegree++;
G.vertices[i].degree++;
}
while(p!
=NULL)
{
G.vertices[i].degree++;
p=p->nextarc;
}
printf("\n%d'sindegree:
%d,degree:
%d",G.vertices[i].data,G.vertices[i].indegree,G.vertices[i].degree);
}
voidDe_Ingree(ALGraph&G)
{
inti,n,m;
for(i=0;i{
Degree(G,i);
}
}
//****************遍历*******************************
boolvisited[MAXSIZE];
voidDFS(ALGraphG,intv)
{
ArcNode*p;
visited[v]=true;
printf("%3d",G.vertices[v].data);
p=G.vertices[v].firstarc;
while(p)
{
if(!
visited[p->adjvex])
DFS(G,p->adjvex);
p=p->nextarc;
}
}
voidDFSTraverse(ALGraphG)
{
printf("\nshowDFStraverresult:
\n");
for(intv=0;v{
visited[v]=false;
}
for(v=0;vif(!
visited[v])
DFS(G,v);
}
intFirstAdjvex(ALGraphG,VNodev)
{
if(v.firstarc!
=NULL)
returnv.firstarc->adjvex;
return1;
}
intNextAdjvex(ALGraphG,VNodev,intw)
{
ArcNode*p;
p=v.firstarc;
while(p!
=NULL&&p->adjvex!
=w)
{
p=p->nextarc;
}
if(p->adjvex==w&&p->nextarc!
=NULL)
{
p=p->nextarc;
returnp->adjvex;
}
if(p->adjvex==w&&p->nextarc==NULL)
return-1;
return1;
}
voidBFSTraverse(ALGraphG)
{
SqQueueQ;
printf("\nshowBFStraverresult:
\n");
inti,e;
for(i=0;ivisited[i]=false;
InitQueue(Q);
for(i=0;i{
if(!
visited[i])
{
visited[i]=true;
printf("%d",G.vertices[i].data);
EnQueue(Q,i);
while(!
QueueEmpty(Q))
{
DeQueue(Q,e);
for(intu=FirstAdjvex(G,G.vertices[e]);u>=0;u=NextAdjvex(G,G.vertices[e],u))
{
if(!
visited[u])
{
visited[u]=true;
printf("%d",G.vertices[u].data);
EnQueue(Q,u);
}
}
}
}
}
}
//****************主函数*******************************
intmain()
{
ALGraphG;
CreateUDG(G);
De_Ingree(G);
DFSTraverse(G);
BFSTraverse(G);
return0;
}
三、实验说明:
1.类型定义(邻接表存储)#defineMAX_VERTEX_NUM8//顶点最大个数typedefstructArcNode
{intadjvex;
structArcNode*nextarc;
intweight;//边的权
}ArcNode;//表结点#defineVertexTypeint//顶点元素类型
typedefstructVNode
{intdegree,indegree;//顶点的度,入度VertexTypedata;
ArcNode*firstarc;
}VNode/*头结点*/,AdjList[MAX_VERTEX_NUM];typedefstruct{AdjListvertices;
intvexnum,arcnu