数据结构 图.docx
- 文档编号:8851498
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:16
- 大小:53.12KB
数据结构 图.docx
《数据结构 图.docx》由会员分享,可在线阅读,更多相关《数据结构 图.docx(16页珍藏版)》请在冰豆网上搜索。
数据结构图
实验十二图
1、实验项目名称
图
2、实验目的
1.通过实验理解图的逻辑结构。
2.通过实验掌握图的几种存储结构。
3.通过实验掌握图的遍历操作。
三、实验基本原理
1、数据结构
(1)邻接表:
#defineMAX20//最大节点数
typedefintVertexType;
typedefintInfoType;
typedefstructArcNode{
intadjvex;
structArcNode*nextarc;
InfoType*info;
}ArcNode;
typedefstructVNode{
VertexTypedata;
ArcNode*firstarc;
}VNode,AdjList[MAX];
typedefstruct{
AdjListvertices;
intvexnum,arcnum;//顶点数边数
}ALGraph;
(2)邻接矩阵
#difineINFINITYINT_MAX
#difineMAX20
typedefenum{
DG,DN,UDG,UDN
}GraphKind;
typedefstructArcCell{
VRTypeadj;
InfoType*info;
}ArcCell,AdjMatrix[MAX][MAX];
typedefstruct{
VertexTypevexs[MAX];
AdjMatrixarcs;
intvexnum,arcnum;
GraphKindkind;
}MGraph;
(3)十字链表
#defineMAX20
typedefstructArcBox{
inttailvex,headvex;
structArcBox*hlink,tlink;
InfoType*info;
}ArcBox;
typedefstructVexNode{
VertexTypedata;
ArcBox*firstin,*fistout;
}VexNode;
typedefstruct{
VexNodexlist[MAX];
intvexnum,arcnum;
}OLGraph;
2、算法思想
图的储存方式有很多种,本次实验是写了用邻接表方式储存的操作,包括创建和遍历。
邻接表创建无向图,需要用两种结点,一种结点是来存储图的相邻边的信息,需要用弧所指顶点的位置、指向下一条顶点的指针;一种是存储图的结点的相关信息,需要有顶点的信息,以及指向第一条依附该顶点的弧的指针。
邻接矩阵是存储图的另外一种表示方法,其中的一种应用是用普利姆算法和克鲁斯算法找图的最小生成树。
普利姆算法是从一个点出发找到依附它的最小的并且不能构成环一条边,然后找边依附的另外一个结点做相同操作;克鲁斯算法是按照边从小到大的顺序构建,如果构成环则跳过,当所有的顶点都链接后,算法结束。
3、算法描述
见代码
四、主要仪器设备及耗材
1、硬件环境
2、开发平台
DevC++
5、实验步骤
1.分析题目,确定数据结构类型,设计正确的算法;
2.编写代码;
3.运行及调试程序;
4.修改程序,提高其健壮性。
六、实验数据及处理结果
1、程序清单
#include
#include
usingnamespacestd;
#defineMAX20//最大节点数
typedefintVertexType;
typedefintInfoType;
typedefstructArcNode{
intadjvex;
structArcNode*nextarc;
InfoType*info;
}ArcNode;
typedefstructVNode{
VertexTypedata;
ArcNode*firstarc;
}VNode,AdjList[MAX];
typedefstruct{
AdjListvertices;
intvexnum,arcnum;//顶点数边数
}ALGraph;
inti,j,m,n;
voidCreatGraph2(ALGraph&G){//无向图
cout<<"1.请输入顶点数和边数:
";
cin>>G.vexnum>>G.arcnum;
cout<<"请依次输入顶点信息:
";
for(inti=0;i cin>>G.vertices[i].data; G.vertices[i].firstarc=NULL; } cout<<"2.请输入相邻的顶点组: "< for(inti=0;i cout<<"请输入第"< "< cin>>m>>n; ArcNode*AN; AN=(ArcNode*)malloc(sizeof(ArcNode)); AN->adjvex=m; //m=1,n=2 for(inti=0;i if(G.vertices[i].data==n){ AN->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=AN; } } AN=(ArcNode*)malloc(sizeof(ArcNode)); AN->adjvex=n; for(inti=0;i if(G.vertices[i].data==m){ AN->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=AN; } } } }//CreatGraph1 voidPrintGraph2(ALGraphG){ for(inti=0;i { cout< while(G.vertices[i].firstarc! =NULL) { cout< G.vertices[i].firstarc=G.vertices[i].firstarc->nextarc; } cout< } } voidTraveGraph2(ALGraphG){ cout<<"图的所有顶点为: "; for(inti=0;i cout< cout< } //有向图 voidCreatGraph1(ALGraph&G){//有向图 cout<<"1.请输入顶点数和边数: "; cin>>G.vexnum>>G.arcnum; cout<<"请依次输入顶点信息: "; for(inti=0;i cin>>G.vertices[i].data; G.vertices[i].firstarc=NULL; } cout<<"2.请输入相邻的顶点组: "< for(inti=0;i cout<<"请输入第"< "< cin>>m>>n; ArcNode*AN; AN=(ArcNode*)malloc(sizeof(ArcNode)); AN->adjvex=n; //m=1,n=2 for(inti=0;i if(G.vertices[i].data==m){ AN->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=AN; } } } }//CreatGraph0 //打印、遍历同1 //深度优先遍历从第V个顶点出发 voidDFS(AlGraphG,intv) { ArcNode*p; cout< visited[v]=1; p=G.vertices[v].firstarc; while(p! =NULL) {if(! visited[p->adjvex])//判断该节点是否访问过 DFS(G,p->adjvex); p=p->nextarc; } return; } voidDFSTravers(AlGraphG) { intv; for(v=1;v<=G.vexnum;v++) visited[v]=0; for(v=1;v<=G.vexnum;v++) { if(visited[v]==0) DFS(G,v); } } intmain(){ cout<<"**********************************图的邻接表表示****************************"< intop;ALGraphG; cout<<"按1进行有向图创建;"<<"2进行无向图创建;"<<"0退出"< cin>>op; while(op){ switch(op){ case1: CreatGraph1(G); cout<<"构建的邻接表为: "< PrintGraph2(G); TraveGraph2(G); break; case2: CreatGraph2(G); cout<<"构建的邻接表为: "< PrintGraph2(G); TraveGraph2(G); break; } cout<<"按1进行有向图创建;"<<"2进行无向图创建;"<<"0退出"< cin>>op; } } #include #include #include #include #defineMAX_VERTEX_NUM20 #defineINFINITYINT_MAX usingnamespacestd; typedefstructArcell{ doubleadj; }Arcell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedefstruct{ charvexs[MAX_VERTEX_NUM];//节点数组 AdjMatrixarcs;//邻接矩阵 intvexnum,arcnum;//图的当前节点数和弧数 }MGraph; //普利姆算法 typedefstructVnode{ charadjvex;//节点 intlowcost;//权值 }Pnode,Closedge[MAX_VERTEX_NUM];//记录顶点集U到V-U的代价最小的边的辅助数组定义 //克鲁斯 typedefstructKnode{ charv1;//节点1 charv2;//节点2 intvalue;//权值 }Knode,Dgevalue[MAX_VERTEX_NUM]; intLocateVex(MGraphG,charch); intMinimum(MGraphG,Closedgeclosedge); voidMiniSpanTree_PRIM(MGraphG,charu); voidSortdge(Dgevalue&dgevalue,MGraphG); intCreateG(MGraph&G,Dgevalue&dgevalue)//构造无向加权图的邻接矩阵 { inti,j,k; cout<<"请输入图的顶点数和边数: "; cin>>G.vexnum>>G.arcnum; cout< for(i=0;i cin>>G.vexs[i]; for(i=0;i for(j=0;j G.arcs[i][j].adj=INT_MAX; cout< for(k=0;k { cout<<"请输入第"< "; cin>>dgevalue[k].v1>>dgevalue[k].v2>>dgevalue[k].value; i=LocateVex(G,dgevalue[k].v1); j=LocateVex(G,dgevalue[k].v2); G.arcs[i][j].adj=dgevalue[k].value; G.arcs[j][i].adj=G.arcs[i][j].adj; } cout< "< for(i=0;i { for(j=0;j { if(G.arcs[i][j].adj==INT_MAX) cout< else cout< } cout< } return1; } //确定顶点ch在图G.vexs中的位置 intLocateVex(MGraphG,charch) { inta; for(inti=0;i if(G.vexs[i]==ch) a=i; returna; } //普里姆算法求最小生成树 voidMiniSpanTree_PRIM(MGraphG,charu) { inti,j,k; Closedgeclosedge; k=LocateVex(G,u);//定位顶点u在图的顶点向量中的位置下标 for(j=0;j { if(j! =k) { closedge[j].adjvex=u; closedge[j].lowcost=G.arcs[k][j].adj; } } closedge[k].lowcost=0;//初始,U={u} for(i=1;i { k=Minimum(G,closedge);//求出T的下一个结点: 第k顶点 cout< closedge[k].lowcost=0;//第k顶点并入u集 for(j=0;j { if(G.arcs[k][j].adj { closedge[j].adjvex=G.vexs[k]; closedge[j].lowcost=G.arcs[k][j].adj; } } } } //求closedge中权值最小的边,并返回其顶点在vexs中的位置 intMinimum(MGraphG,Closedgeclosedge) { inti,j; doublek=INT_MAX; for(i=0;i { if(closedge[i].lowcost! =0&&closedge[i].lowcost { k=closedge[i].lowcost; j=i; } } returnj; } //克鲁斯卡尔算法求最小生成树 voidMiniSpanTree_KRSL(MGraphG,Dgevalue&dgevalue) { intp1,p2,i,j; intbj[MAX_VERTEX_NUM];//标记数组 for(i=0;i bj[i]=i; Sortdge(dgevalue,G);//将所有权值按从小到大排序 for(i=0;i { p1=bj[LocateVex(G,dgevalue[i].v1)]; p2=bj[LocateVex(G,dgevalue[i].v2)]; if(p1! =p2) { cout< for(j=0;j { if(bj[j]==p2) bj[j]=p1; } } } } //按权值按从小到大排序 voidSortdge(Dgevalue&dgevalue,MGraphG) { inti,j; doubletemp; charv1,v2; for(i=0;i { for(j=i;j { if(dgevalue[i].value>dgevalue[j].value) { temp=dgevalue[i].value; dgevalue[i].value=dgevalue[j].value; dgevalue[j].value=temp; v1=dgevalue[i].v1; dgevalue[i].v1=dgevalue[j].v1; dgevalue[j].v1=v1; v2=dgevalue[i].v2; dgevalue[i].v2=dgevalue[j].v2; dgevalue[j].v2=v2; } } } } intmain() { inti,j; MGraphG; charu; Dgevaluedgevalue; CreateG(G,dgevalue); cout<<"请输入起始点: "; cin>>u; cout< MiniSpanTree_PRIM(G,u); cout< MiniSpanTree_KRSL(G,dgevalue); } 2、运行结果 (1)有向图的操作 (2)无向图的操作 (3)普利姆算法和克鲁斯算法 7、思考讨论题或体会或对改进实验的建议 这次实验是做图的相关储存,图是一种很复杂的数据结构,刚开始的时候很不明白它的存储结构,后来经过老师的讲解,瞬间恍然大悟,做实验的时候,虽然觉得它很复杂,但是基本的思想还是有的; 在实验中涉及赋值与交换的一定要万般小心,一个不注意就会导致程序难以运行,细心也是我在这次实验中体会最深的。 八、参考资料 参考1: 《数据结构C语言版》清华大学出版社
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构