数据结构报告3.docx

上传人:b****7 文档编号:9263349 上传时间:2023-02-03 格式:DOCX 页数:34 大小:80.26KB
下载 相关 举报
数据结构报告3.docx_第1页
第1页 / 共34页
数据结构报告3.docx_第2页
第2页 / 共34页
数据结构报告3.docx_第3页
第3页 / 共34页
数据结构报告3.docx_第4页
第4页 / 共34页
数据结构报告3.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

数据结构报告3.docx

《数据结构报告3.docx》由会员分享,可在线阅读,更多相关《数据结构报告3.docx(34页珍藏版)》请在冰豆网上搜索。

数据结构报告3.docx

数据结构报告3

中南大学

 

数据结构实验报告

 

 

 

数据结构实验报告3

1.实验内容

图的操作算法

实现图的常用操作算法:

包括建立图的存储结构、深度优先搜索和广度优先搜索,求图的最小生成树、拓扑排序、最短路径等。

2.程序设计思路

1.最小生成树

Prim算法

设G=(V,E)是连通带权图,V={1,2,…,n}。

构造G的最小生成树Prim算法的基本思想是:

首先置S={1},然后,只要S是V的真子集,就进行如下的贪心选择:

选取满足条件i∈S,j∈V–S,且c[i][j]最小的边,将顶点j添加到S中。

这个过程一直进行到S=V时为止。

在这个过程中选取到的所有边恰好构成G的一棵最小生成树。

Kruskal算法

当图的边数为e时,Kruskal算法所需的时间是O(eloge)。

当e=Ω(n^2)时,Kruskal算法比Prim算法差;但当e=o(n^2)时,Kruskal算法比Prim算法好得多。

2.图的深度优先搜索

递归实现

(1)访问顶点v;visited[v]=1;//算法执行前visited[n]=0

(2)w=顶点v的第一个邻接点;

(3)while(w存在)

if(w未被访问)

从顶点w出发递归执行该算法;

w=顶点v的下一个邻接点;

非递归实现

(1)栈S初始化;visited[n]=0;

(2)访问顶点v;visited[v]=1;顶点v入栈S

(3)while(栈S非空)

x=栈S的顶元素(不出栈);

if(存在并找到未被访问的x的邻接点w)

访问w;visited[w]=1;

w进栈;

3.拓扑排序

(1)在AOV网络中选一个没有直接前驱的顶点,并输出之;

(2)从图中删去该顶点,同时删去所有它发出的有向边;

(3)重复以上步骤,直到全部顶点均已输出,拓扑有序序列形成,拓扑排序完成;或者图中还有未输出的顶点,但已跳出处理循环。

这说明图中还剩下一些顶点,它们都有直接前驱,再也找不到没有前驱的顶点了。

这时AOV网络中必定存在有向环。

(拓扑排序完成;AOV网络中必定存在有向环)

4.了解了最短路径算法

单源最短路径问题:

已知有向带权图(简称有向网)G=(V,E),找出从某个源点s∈V到V中其余各顶点的最短路径。

迪杰斯特拉(Dijkstra)算法求单源最短路径。

3.主要算法

1、最小生成树

#include

#include

#include

#defineMAX_VERTEX_NUM20

#defineOK1

#defineERROR0

#defineMAX1000

usingnamespacestd;

typedefstructArcell

{

doubleadj;

}Arcell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedefstruct

{

charvexs[MAX_VERTEX_NUM];//节点数组

AdjMatrixarcs;//邻接矩阵

intvexnum,arcnum;//图的当前节点数和弧数

}MGraph;

typedefstructPnode//用于普利姆算法

{

charadjvex;//节点

doublelowcost;//权值

}Pnode,Closedge[MAX_VERTEX_NUM];//记录顶点集U到V-U的代价最小的边的辅助数组定义

typedefstructKnode//用于算法中存储一条边及其对应的2个节点

{

charch1;//节点1

charch2;//节点2

doublevalue;//权值

}Knode,Dgevalue[MAX_VERTEX_NUM];

intCreateUDG(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=MAX;

}

}

cout<<"请输入一条边依附的定点及边的权值:

"<

for(k=0;k

{

cin>>dgevalue[k].ch1>>dgevalue[k].ch2>>dgevalue[k].value;

i=LocateVex(G,dgevalue[k].ch1);

j=LocateVex(G,dgevalue[k].ch2);

G.arcs[i][j].adj=dgevalue[k].value;

G.arcs[j][i].adj=G.arcs[i][j].adj;

}

returnOK;

}

intLocateVex(MGraphG,charch)//确定节点ch在图G.vexs中的位置

{

inta;

for(inti=0;i

{

if(G.vexs[i]==ch)

a=i;

}

returna;

}

//typedefstructPnode//用于普利姆算法

//{

//charadjvex;//节点

//doublelowcost;//权值

//}Pnode,Closedge[MAX_VERTEX_NUM];//记录顶点集U到V-U的代价最小的边的辅助数组定义

voidMiniSpanTree_PRIM(MGraphG,charu)//普利姆算法求最小生成树

{

inti,j,k;

Closedgeclosedge;

k=LocateVex(G,u);

for(j=0;j

{

if(j!

=k)

{

closedge[j].adjvex=u;

closedge[j].lowcost=G.arcs[k][j].adj;

}

}

closedge[k].lowcost=0;

for(i=1;i

{

k=Minimum(G,closedge);

cout<<"("<

closedge[k].lowcost=0;

for(j=0;j

{

if(G.arcs[k][j].adj

{

closedge[j].adjvex=G.vexs[k];

closedge[j].lowcost=G.arcs[k][j].adj;

}

}

}

}

intMinimum(MGraphG,Closedgeclosedge)//求closedge中权值最小的边,并返回其顶点在vexs中的位置

{

inti,j;

doublek=1000;

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].ch1)];

p2=bj[LocateVex(G,dgevalue[i].ch2)];

if(p1!

=p2)

{

cout<<"("<

for(j=0;j

{

if(bj[j]==p2)

bj[j]=p1;

}

}

}

}

voidSortdge(Dgevalue&dgevalue,MGraphG)//对dgevalue中各元素按权值按从小到大排序

{

inti,j;

doubletemp;

charch1,ch2;

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;

ch1=dgevalue[i].ch1;

dgevalue[i].ch1=dgevalue[j].ch1;

dgevalue[j].ch1=ch1;

ch2=dgevalue[i].ch2;

dgevalue[i].ch2=dgevalue[j].ch2;

dgevalue[j].ch2=ch2;

}

}

}

}

voidmain()

{

inti,j;

MGraphG;

charu;

Dgevaluedgevalue;

CreateUDG(G,dgevalue);

cout<<"图的邻接矩阵为:

"<

for(i=0;i

{

for(j=0;j

cout<

cout<

}

cout<<"=============普利姆算法===============\n";

cout<<"请输入起始点:

";

cin>>u;

cout<<"构成最小代价生成树的边集为:

\n";

MiniSpanTree_PRIM(G,u);

cout<<"============克鲁斯科尔算法=============\n";

cout<<"构成最小代价生成树的边集为:

\n";

MiniSpanTree_KRSL(G,dgevalue);

}

2、拓扑排序

#include"stdio.h"

#defineMAX_VERTEX_NUM20

#include"conio.h"

#include"stdlib.h"

#defineSTACK_INIT_SIZE16

#defineSTACKINCREMENT5

typedefintSElemType;

typedefcharVertexType;

typedefstruct

{

SElemType*base;

SElemType*top;

intstacksize;

}SqStack;//我们依然用邻接表来作图的存储结构

typedefstructArcNode{

intadjvex;

structArcNode*nextarc;

intinfo;

}ArcNode;//表结点类型

typedefstructVNode{

VertexTypedata;

intcount;

ArcNode*firstarc;

}VNode,AdjList[MAX_VERTEX_NUM];//头结点

typedefstruct{

AdjListvertices;//邻接表

intvexnum,arcnum;

}ALGraph;

intInitStack(SqStack&S)

{

S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));

if(!

S.base)exit(-1);

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

return1;

}//InitStack

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(-1);

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}//if

*(S.top)=e;

S.top++;

return1;

}//Push

intPop(SqStack&S,SElemType&e)

{

if(S.top==S.base)return0;

--S.top;

e=*S.top;

return1;

}//Pop

intStackEmpty(SqStack&S)

{

if(S.top==S.base)return1;

elsereturn0;

}//StackEmpty

intLocateVex(ALGraphG,charu)

{

inti;

for(i=0;i

{if(u==G.vertices[i].data)returni;}

if(i==G.vexnum){printf("Erroru!

\n");exit

(1);}

return0;

}

voidCreateALGraph_adjlist(ALGraph&G)

{

inti,j,k,w;

charv1,v2,enter;

ArcNode*p;

printf("Inputvexnum&arcnum:

\n");

scanf("%d",&G.vexnum);

scanf("%d",&G.arcnum);

printf("InputVertices(以回车隔开各个数据):

\n");

for(i=0;i

{scanf("%c%c",&enter,&G.vertices[i].data);//注意点,解说

G.vertices[i].firstarc=NULL;

}//for

printf("InputArcs(v1,v2,w)以回车分开各个数据:

\n");

for(k=0;k

{

scanf("%c%c",&enter,&v1);

scanf("%c%c",&enter,&v2);

scanf("%d",&w);

i=LocateVex(G,v1);

j=LocateVex(G,v2);

p=(ArcNode*)malloc(sizeof(ArcNode));

p->adjvex=j;

p->info=w;

p->nextarc=G.vertices[i].firstarc;//前插法,即每次都插入到头结点的后面

G.vertices[i].firstarc=p;

printf("Next\n");

}//for

return;

}//CreateALGraph_adjlist

voidFindInDegree(ALGraph&G)

inti,j;

for(i=0;i

{

G.vertices[i].count=0;

}//for

for(j=0;j

{

//G.vertices[i].count++;

for(ArcNode*p=G.vertices[j].firstarc;p;p=p->nextarc)

G.vertices[p->adjvex].count++;

}//for

}//FindInDegree

intTopoSort(ALGraph&G)

{

SqStackS;

FindInDegree(G);

InitStack(S);

for(inti=0;i

if(G.vertices[i].count==0)Push(S,i);

intcountt=0;

while(!

StackEmpty(S))

{

inti,m;

m=Pop(S,i);

printf("%c",G.vertices[i].data);++countt;

for(ArcNode*p=G.vertices[i].firstarc;p;p=p->nextarc)

{intk;

k=p->adjvex;

if(!

(--G.vertices[k].count))Push(S,k);

}//for

}//while

if(countt

elsereturn1;

}//TopoSort

intmain()

{

ALGraphG;

CreateALGraph_adjlist(G);

TopoSort(G);

return1;

}

3、深度优先搜索和广度优先搜索

深度优先搜索:

图的深度优先遍历类似于树的前序遍历。

采用的搜索方法的特点是尽可能先对纵深方向进行搜索。

这种搜索方法称为深度优先搜索

广度优先搜索:

图的广度优先遍历BFS算法是一个分层搜索的过程,和树的层序遍历算法类同,它也需要一个队列以保持遍历过的顶点顺序,以便按出队的顺序再去访问这些顶点的邻接顶点。

#include

#include

#include

#defineMAX_VERTEX_NUM20

typedefstructArcNode{

intadjvex;

structArcNode*nextarc;

//InfoType*info;

}ArcNode;

typedefstructLinkNode{

ArcNode*parc;//存储指针地址

structLinkNode*next;//指向一下个结点

}LinkNode;

typedefstructVNode{

charcData;//顶点元素值

ArcNode*firstarc;//指向第一条依附于该点的边

}VNode,AdjList[MAX_VERTEX_NUM];

typedefstruct{

AdjListvertices;

intvexnum;//图的当前顶点数和弧数

intarcnum;

}ALGraph;

intVisited[MAX_VERTEX_NUM];

intPrintCheck(ALGraph*pag)

{

inti;

ArcNode*p;

printf("\nChecktheGraph!

\n");

printf("No\tdata\tnext\tnext\t.....\n");

for(i=0;ivexnum;i++)

{

printf("%d\t%c\t",i,pag->vertices[i].cData);

p=pag->vertices[i].firstarc;

while(p)

{

printf("%d\t",p->adjvex);

p=p->nextarc;

}

printf("\n");

}

return1;

}

intCreateGraph(ALGraph*pag,intstart,intend)

{

ArcNode*arcNodes=(ArcNode*)malloc(sizeof(ArcNode));

ArcNode*arcNodee=(ArcNode*)malloc(sizeof(ArcNode));

ArcNode*p;

if(!

arcNodes||!

arcNodee)return0;//从start->end生成关系

arcNodes->adjvex=end;//下一结点的位置

p=pag->vertices[start].firstarc;

if(!

p)//第一个结点单独构造

{

arcNodes->nextarc=pag->vertices[start].firstarc;

pag->vertices[start].firstarc=arcNodes;

}

else{

while(p->nextarc)p=p->nextarc;

p->nextarc=arcNodes;

arcNodes->nextarc=NULL;

}//end->start的关系生成

arcNodee->adjvex=start;//下一结点的位置

p=pag->vertices[end].firstarc;

if(!

p)//第一个结点单独构造

{

arcNodee->nextarc=pag->vertices[end].firstarc;

pag->vertices[end].firstarc=arcNodee;

}

else{

while(p->nextarc)p=p->nextarc;

p->nextarc=arcNodee;

arcNodee->nextarc=NULL;

}

return1;

}

voidDFSTraverse(ALGraphag,intstart)

{

LinkNode*Stack=(LinkNode*)mal

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

当前位置:首页 > 工作范文 > 行政公文

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

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