实验四图的操作及应用讲解.docx
《实验四图的操作及应用讲解.docx》由会员分享,可在线阅读,更多相关《实验四图的操作及应用讲解.docx(19页珍藏版)》请在冰豆网上搜索。
![实验四图的操作及应用讲解.docx](https://file1.bdocx.com/fileroot1/2023-2/25/ed6b9b7d-2465-4fb9-b3ab-6fa533462959/ed6b9b7d-2465-4fb9-b3ab-6fa5334629591.gif)
实验四图的操作及应用讲解
实验四图的操作及应用
实验课程名:
数据结构与算法
一、实验目的及要求
1、理解图的基本概念及术语。
2、掌握图的两种存储结构(邻接矩阵和邻接表)的表示方法。
3、熟练掌握图的两种遍历(深度优先搜索遍历和广度优先搜索遍历)的算法思想、步骤,并能列出在两种存储结构上按上述两种遍历算法得到的序列。
二、实验内容
任务一:
构造如图1所示的图的邻接矩阵存储结构和邻接表存储结构。
图1
解答:
(1)源代码:
#include
#include
#include
#defineINFINITY1000
#defineMAX_VERTEX_NUM20
#defineOK1
#defineSTARTS"********************************"
typedefenum{DG,DN,UDG,UDN}GraphKind;
typedefintEType;
typedefintInfoType;
typedefintVertexType;
typedefstructArcCell
//definestructureMGraph
{
ETypeadj;
InfoType*info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedefstruct
{
VertexTypevexs[MAX_VERTEX_NUM];
AdjMatrix
arcs;
intvexnum,arcnum;
GraphKindkind;
}MGraph;
intCreatUDN(MGraph&G)
//CreatUDN()sub-function
{
intIncInfo,i,j,k,v1,v2,w;
cout<";
cin>>G.vexnum;
//inputthenumberofvex
cout<<"PleaseinputthenumberofG.arcnum(eg,G.arcnum=4):
";
cin>>G.arcnum;
//inputthenumberofarc
cout<<"PleaseinputIncInfo(0fornone):
";
cin>>IncInfo;
for(i=0;ifor(j=0;j{
G.arcs[i][j].adj=INFINITY;
//initialG.arcs[i][j].adj
G.arcs[i][j].info=NULL;
//initialG.arcs[i][j].info
}
cout<<"Pleseinputarc(V1-->V2),Forexample:
(V1=1,V2=3),(V1=2,V2=4)..."<for(k=0;k//inputarc(v1,v2)
{
cout<";
cin>>v1;
//inputv1
cout<<"Pleaseinputthe"<";
cin>>v2;
//inputv2
cout<<"Pleaseinputthe"<";
cin>>w;
//inputweight
i=v1;
j=v2;
while(i<1||i>G.vexnum||j<1||j>G.vexnum)
//if(v1,v2)illegal,again
{
cout<<"Pleaseinputthe"<";
cin>>v1;
cout<<"Pleaseinputthe"<";
cin>>v2;
cout<<"Pleaseinputthe"<";
cin>>w;
i=v1;
j=v2;
}//whileend
i--;
j--;
G.arcs[i][j].adj=G.arcs[j][i].adj=w;
//weight
cout<<"G.arcs["<
if(IncInfo)
{
cout<<"Pleaseinputthe"<";
cin>>*G.arcs[i][j].info;
}
}//forend
return(OK);
}//CreatUDN()end
voidGprintf(MGraphG)//打印邻接矩阵
{
cout<<"邻接矩阵数组为:
\n";
for(inti=0;i{
for(intk=0;kcout<cout<}
}
/*
邻接表
*/
typedefstructArcNode
//definestructureALGraph
{
intadjvex;
structArcNode*nextarc;
InfoType*info;
}ArcNode;
typedefstructVNode
{
VertexTypedata;
ArcNode*firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;
intkind;
}ALGraph;
intCreateDG(ALGraph&G)
//CreateDG()subfunction
{
intIncInfo,i,j,k,v1,v2,w;
cout<";
cin>>G.vexnum;
//inputthenumberofvex
cout<<"PleaseinputthenumberofG.arcnum(eg,G.arcnum=4):
";
cin>>G.arcnum;
//inputthenumbeofarc
cout<<"PleaseinputthenumberofIncInfo(0fornone):
";
cin>>IncInfo;
//ifnoinformation,input0
for(i=0;i{
G.vertices[i].data=i;//initialG.vertices[i].data
G.vertices[i].firstarc=NULL;
//initialG.vertices[i].firstarc
}
cout<<"Pleseinputarc(V1-->V2),Forexample:
(V1=1,V2=3),(V1=2,V2=4)..."<for(k=0;k//inputarc(v1,v2)
{
cout<";
cin>>v1;
cout<<"Pleaseinputthe"<";
cin>>v2;
i=v1;
j=v2;
while(i<1||i>G.vexnum||j<1||j>G.vexnum)//if(v1,v2)illegal
{
cout<";
cin>>v1;
cout<<"Pleaseinputthe"<";
cin>>v2;
i=v1;
j=v2;
}//whileend
i--;
j--;
ArcNode*p;
p=(ArcNode*)malloc(sizeof(ArcNode));
//allocatememory
if(!
p)
{
cout<<"Overflow!
";
return(0);
}
p->adjvex=j;//assignp->adjvex
p->nextarc=G.vertices[i].firstarc;
p->info=NULL;
G.vertices[i].firstarc=p;
if(IncInfo)
{
cout<<"Pleaseinputtheinfo:
";
cin>>*(p->info);//inputinformation
}
}//forend
return(OK);
}//CreateDG()end
intmain()
{
MGraphMG;
ALGraphAG;
inta=-1;
while(a!
=0)
{
cout<cout<<"
(1)邻接矩阵(无向网)\t"<<"
(2)邻接表(有向图)\t"<<"(3)退出"<cout<<"选择存储方式:
";
cin>>a;
switch(a)
{
case1:
{CreatUDN(MG);Gprintf(MG);break;}
case2:
CreateDG(AG);break;
case3:
a=0;break;
default:
cout<<"选择错误\n"<}
}
return0;
}
(2)运行结果:
(3)运行结果分析:
运用数组与链表的结合来实现
任务二:
用邻接表的存储结构创建一个如图2所示的图a,分别打印出这两个图的深度优先遍历和广度优先遍历的结点信息序列。
解答:
(1)源代码:
#include
#include
#include
usingnamespacestd;
#defineERROR1
#defineMAX_VERTEX_NUM100
typedefstructArcNode{
intadjvex;
structArcNode*nextarc;
stringinfo;
}ArcNode;
typedefstructVNode{
chardate;
ArcNode*firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct{
AdjListvertices;
intvexnum,arcnum;//当前图的vexnum顶点数和arcnum弧数
intkind;
}ALGraph;
intLocateVex(ALGraph&G,char&v1)
{
inti;
for(i=0;i{
if(G.vertices[i].date==v1)
returni;
}
if(i>=G.vexnum)
returnERROR;
else
return0;
}
voidCreateDG(ALGraph&G)
{
ArcNode*p,*q;
charv1,v2;
charv;
inti,j,k,n;
cout<<"请输入图的顶点数和弧数:
"<cin>>G.vexnum;
cin>>G.arcnum;
cout<<"请输入顶点:
"<for(i=0;i{
cin>>v;
G.vertices[i].date=v;
G.vertices[i].firstarc=NULL;
}
cout<<"请输入弧尾和弧头:
";
for(k=0;k{
cin>>v1;
cin>>v2;
i=LocateVex(G,v1);j=LocateVex(G,v2);
if(G.vertices[i].firstarc==NULL)
{
p=(ArcNode*)newArcNode;
G.vertices[i].firstarc=p;
q=G.vertices[i].firstarc;
}
else
{
q=G.vertices[i].firstarc;
for(n=0;nnextarc)
{
if(!
q->nextarc)
break;
}
p=(ArcNode*)newArcNode;
q->nextarc=p;
q=q->nextarc;
}
q->adjvex=j;
q->nextarc=NULL;
}
cout<<"图构建成功!
";
}
//----------------深度优先遍历--------------------//
boolvisited[MAX_VERTEX_NUM];
intFirstAdjVex(ALGraph&G,intv)
{
inti;
intn=-1;
ArcNode*p;
p=G.vertices[v].firstarc;
if(p)
{
i=p->adjvex;
if(visited[i]==false)
n=i;
}
returnn;
}
intNextAdjVex(ALGraph&G,intv)
{
inti;
intn=-1;
ArcNode*p;
p=G.vertices[v].firstarc;
for(i=p->adjvex;i=NULL;)
{
i=p->adjvex;
if(visited[i]==false)
{
n=i;
break;
}
else
p=p->nextarc;
}
returnn;
}
voidVisitFuc(ALGraph&G,intv)
{
cout<}
voidDFS(ALGraph&G,intv)
{
intw;
visited[v]=true;
VisitFuc(G,v);
for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v))
if(!
visited[w])DFS(G,w);
}
voidDFSTraverse(ALGraph&G)
{
intv;
for(v=0;vvisited[v]=false;
cout<<"深度优先搜索:
"<for(v=0;v{
if(!
visited[v])
DFS(G,v);
}
}
//----------------广度优先遍历--------------------//
voidBFSTraverse(ALGraph&G)
{
intv;
intw;
queueq;//STL队列
for(v=0;vvisited[v]=false;
//InitQueue(Q);
cout<<"广度优先搜索:
";
for(v=0;v{
if(!
visited[v])
{
visited[v]=true;
VisitFuc(G,v);
q.push(v);//v进队
while(q.empty()!
=true)
{
v=q.front();
q.pop();
for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v))
{if(!
visited[w])
{
visited[w]=true;
VisitFuc(G,w);
q.push(w);
}
}
}
}
}
}
/////////////////////////////////////////////////////////////////
voidmenu()
{
cout<<'\n';
cout<<"//---------------图的基本操作---------------//"<cout<<"**1、图的构建**"<cout<<"**2、深度优先遍历**"<cout<<"**3、广度优先遍历**"<cout<<"--------------------------------------------"<cout<<"请输入数字进行选择:
"<}
intmain()
{
ALGraphG;
inti;
menu();
cin>>i;
while(i<4)
{
switch(i)
{
case1:
CreateDG(G);break;
case2:
DFSTraverse(G);cout<case3:
BFSTraverse(G);cout<default:
returnERROR;
}
menu();
cin>>i;
}
return0;
}
(2)运行结果:
(3)运行结果分析:
运用图的深度优先和广度优先算法搜索。
3、实验小结
通过本次实验我知道了图的基本概念及术语。
了解了图的两种存储结构(邻接矩阵和邻接表)的表示方法。
熟练掌握图的两种遍历(深度优先搜索遍历和广度优先搜索遍历)的算法思想、步骤,并能列出在两种存储结构上按上述两种遍历算法得到的序列。