算法勘误 图.docx

上传人:b****5 文档编号:7886531 上传时间:2023-01-26 格式:DOCX 页数:16 大小:19.38KB
下载 相关 举报
算法勘误 图.docx_第1页
第1页 / 共16页
算法勘误 图.docx_第2页
第2页 / 共16页
算法勘误 图.docx_第3页
第3页 / 共16页
算法勘误 图.docx_第4页
第4页 / 共16页
算法勘误 图.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

算法勘误 图.docx

《算法勘误 图.docx》由会员分享,可在线阅读,更多相关《算法勘误 图.docx(16页珍藏版)》请在冰豆网上搜索。

算法勘误 图.docx

算法勘误图

邻接表:

#definemax_vertex_num20//最大顶点数

structarcnode

{

intadjvex;

structarcnode*nextarc;

infotypeinfo;//和弧有关的其它信息

};

typedefstructarcnode*arcptr;

typedefstructvexnode

{

vextypevexdata;//和顶点有关的信息

arcptrfirstarc;

}adjlist[max_vertex_num+1];

算法6.1

voidsetadjlist(adjlistgraph)//根据所读入的边,建立图的邻接表graph

{

intv1,v2,i;

for(i=1;i<=max_vertex_num;i++)

graph[i].firstarc=NULL;

arcptrp=NULL,q=NULL;

scanf("%d%d",&v1,&v2);//读入第一条边(v1,v2)

while(v1!

=0)//边的结束标志v1=0

{

q=(arcptr)malloc(sizeof(arcnode));

q->adjvex=v2;q->nextarc=NULL;

if(graph[v1].firstarc==NULL)

graph[v1].firstarc=q;

else

{

p=graph[v1].firstarc;

while(p->nextarc!

=NULL)

p=p->nextarc;

p->nextarc=q;

}

scanf("%d%d",&v1,&v2);//读下一条边

}

}//endofsetadjlist

十字链表形式:

structarctype

{

inttailvex,headvex;

arctype*hlink,*tlink;

};

typedefstructarctype*arclink;

typedefstructvnode

{

vertexdata;

arclinkfirstin,firstout;

}ortholist[max_vertex_num+1];

算法6.2

voidcrt_ortho(ortholistga)//建立有向图的十字链表存储结构

{

intn,e,k,i,j;

arclinkp,q;

scanf("%d%d",&n,&e);//输入顶点和弧的数目

getchar();

for(i=1;i<=n;i++)

{

scanf("%c",&ga[i].data);//输入顶点信息的函数

ga[i].firstin=NULL;ga[i].firstout=NULL;//指针初始化

}

for(k=1;k<=e;k++)

{

scanf("%d%d",&i,&j);//输入弧的信息,i是弧尾顶点的编号,j是弧头顶点的编号

q=(arclink)malloc(sizeof(arclink));

q->headvex=j;

q->tailvex=i;

q->hlink=q->tlink=NULL;

if(NULL==ga[j].firstout)

ga[j].firstout=q;

else

{

p=ga[j].firstout;

while(p->tlink)

p=p->tlink;

p->tlink=q;

}

if(NULL==ga[i].firstin)

ga[i].firstin=q;

else

{

p=ga[i].firstin;

while(p->hlink)

p=p->hlink;

p->hlink=q;

}//将弧结点分别插入到两个链表中

}

}//endofcrt-ortho

边集数组:

structedge//定义边集数组的元素类型

{

intfromvex;//边的起点域

intendvex;//边的终点域

intweight;//边的权值域,对应无权图可省去此域

};

typedefstructedgeedgeset[max_arc_num+1];//定义edgeset为边集数组类型

voidcreatedgeset(vextypegv[],edgesetge,intn,inte)

{//通过从键盘上输入的n个顶点信息和e条边的信息

//建立顶点数组gv和边集数组ge

inti,k,j,w;

for(i=1;i<=n;i++)

scanf("%c",&gv[i]);//输入顶点信息

for(k=1;k<=e;k++)

{

scanf("%d%d%d",&i,&j,&w);//输入一条边的起点、终点和权值

ge[k].fromvex=i;

ge[k].endvex=j;

ge[k].weight=w;

}

}

算法6.2(遍历)

voiddfs(adjlistg,intv0,int*visited)

{

arcptrp;

visite(g,v0);

visited[v0]=1;

p=g[v0].firstarc;

while(p!

=NULL)

{

if(!

visited[p->adjvex])

dfs(g,p->adjvex,visited);

p=p->nextarc;

};

}

voiddfs_begin(adjlistg,intv0,intn)

{//假设图G有n个顶点,用邻接表存储G,DFS遍历图G

arcptrp;

inti;

int*visited;

visited=(int*)malloc(sizeof(int)*(n+1));

for(i=1;i<=n;i++)

visited[i]=0;

visite(g,v0);

visited[v0]=1;

p=g[v0].firstarc;

while(p!

=NULL)

{

if(!

visited[p->adjvex])

dfs(g,p->adjvex,visited);

p=p->nextarc;

};

};//endofdfs

算法6.3:

voidunrecurrentdfs(adjlistg,integerv0,intn)

{//假设图G用邻接表存储,从顶点v0出发非递归地DFS图G,stack是一栈

inti;

arcptrp;

int*visited;

int*stack;

stack=(int*)malloc(sizeof(int)*(n+1));

visited=(int*)malloc(sizeof(int)*(n+1));

for(i=1;i<=n;i++)

visited[i]=0;

visite(g,v0);

visited[v0]=1;

i=1;//i为栈顶指针

stack[i]=v0;//v0进栈

p=g[v0].firstarc;

while(i!

=0)//若栈不空

{

while(p!

=NULL&&visited[p->adjvex])

p=p->nextarc;

if(!

p)//顶点p的所有邻接点都已访问过了

{

i=i-1;//退栈

if(i)

p=g[stack[i]].firstarc;//p取新的栈顶元的邻接点

}

else

{

visite(g,p->adjvex);

visited[p->adjvex]=1;

i=i+1;

stack[i]=p->adjvex;

p=g[p->adjvex].firstarc;

}

}

};//endofunrecurrrntdfs

算法6.4:

voidbfs(adjlistg,intv0,intn)

{//从v0出发广度优先遍历图G

int*visited;

intw,v;

inti;

arcptrp;

visited=(int*)malloc(sizeof(int)*(n+1));

for(i=1;i<=n;i++)

visited[i]=0;

visite(g,v0);

visited[v0]=1;

QueueQ;

iniqueque(&Q);//初始化设置空队列Q

enqueque(&Q,v0);//v0进队列Q

while(!

empty(&Q))//当队列不空时

{

v=dequeque(&Q);//队头元素v出队列

p=g[v].firstarc;//v的第一个邻接点

while(p)//w不是最后一个邻接点

{

w=p->adjvex;

if(!

visited[w])

{

visite(g,w);

visited[w]=1;

enqueque(&Q,w);//顶点w进队列Q

}

p=p->nextarc;//求下一个邻接点

//求顶点w的下一个邻接点,若w是v的最后一个邻接点,则函数nextadj的值为0

}

}

};//endofbfs

算法6.5

voidcomp(adjlistg,intn)

{//用DFS或BFS求g的连通分量

intvi;

int*visited;

visited=(int*)malloc(sizeof(int)*(n+1));

for(vi=1;vi<=n;vi++)

visited[vi]=0;//标志数组初始化

for(vi=1;vi<=n;vi++)

if(!

visited[vi])

{

printf("aconnectedcomponentis");

dfs(g,vi);//深度遍历,标志数组已经初始化,与前面的dfs算法不同

}

}//ofcomp

算法6.6

#definen//...//网的顶点数

#definemaxi//网中权的最大值小于maxi

typedefintcosttype[n+1][n+1];//下标从1开始

voidprim(costtypecost)

{

intlowcost[n+1];

intclosest[n+1];

inti,j,k,min;

for(i=2;i<=n;i++)

{

lowcost[i]=cost[1][i];

closest[i]=1;

}

for(i=2;i

{

min=maxi;

k=0;

for(j=2;j<=n;j++)

if((lowcost[j]

=0))

{

min=lowcost[j];

k=j;

}

printf("%d%5d\n",k,closest[k]);//输出生成树的边

lowcost[k]=0;//k加入u

closest[k]=0;

for(j=2;j<=n;j++)//调整代价

if((cost[k][j]

=0))

{

lowcost[j]=cost[k][j];

closest[j]=k;

}

}//endfor

}//endofprim

Kruscal算法:

这里我想了一个时间复杂度比较好的算法:

#definemax_arc_num//最大边数

#definev_max//最大顶点数

voidkruscal(edgesetgraph,intr[max_arc_num+1])

{//r[]存放结果r[i]为1的话graph[i]边存在

intresult[max_arc_num+1];

inttimes=1;

inttemp;

intnow=1;

inti,j;

intfirst,second;

for(i=1;i<=max_arc_num;i++)

{

result[i]=0;

r[i]=0;

}

while(times

{

first=graph[now].endvex;

second=graph[now].fromvex;

if(0==result[first]&&0==result[second])

{

result[first]=result[second]=now;

r[now]=1;

times++;

}

else

if(0==result[first]||0==result[second])

{

if(0==result[first])

result[first]=result[second];

else

result[second]=result[first];

times++;

r[now]=1;

}

else

if(result[first]!

=result[second])

{

times++;

temp=result[second];

for(j=1;j<=max_arc_num;j++)

{

if(temp==result[j])

result[j]=result[first];

}

r[now]=1;

}

now++;

}

}

算法6.7:

#defineM//图中顶点个数的最大值

#defineNM+1

#defineLENsizeof(structarcnode)

structarcnode

{intadjvex;

structarcnode*nextarc;

};

structvexnode

{intvexdata;

intindegree;

structarcnode*firstarc;

};

voidcrt_adjlist(structvexnodedig[N])//读入有向边,建立图G的邻接表

{

structarcnode*p;

intk,m,i;

for(i=1;i<=N;i++)//表头结点初始化

{

dig[i].vexdata=i;

dig[i].firstarc=NULL;

dig[i].indegree=0;

}

printf("\npleaseinputthearc\n");

scanf("%d%d",&k,&m);//k为弧尾,m为弧头

while(!

(k==0&&m==0))//生成邻接表,表头结点的degree域为每个顶点的入度

{

p=(structarcnode*)malloc(LEN);

p->adjvex=m;

p->nextarc=dig[k].firstarc;//新的弧结点插入在单链表的表头

dig[k].firstarc=p;

dig[m].indegree++;//入度加1

scanf("%d%d",&k,&m);

}

}

voidtopsort(structvexnodedig[N])//拓扑排序

{

intm,i,j,top,k,stack[N];

structarcnode*q;

top=-1;//栈初始化

for(i=1;i<=N;i++)//入度为零的顶点进栈

if(dig[i].indegree==0)

stack[++top]=i;

m=0;//输出顶点的计数器

while(top!

=-1)//栈不空

{

j=stack[top--];//j取栈顶元素,栈顶元素退栈

printf("%5d",dig[j].vexdata);

m++;

q=dig[j].firstarc;//在邻接表上查找j的所有后继k,将k的入度减1

while(q!

=NULL)

{

k=q->adjvex;

if(--dig[k].indegree==0)stack[++top]=k;//若k的入度为零,让k进栈

q=q->nextarc;

}

}

if(m

}

算法6.8:

#defineN6//顶点数

#defineMAX1000//max是计算机允许的最大值

voidshortpath(intcost[N][N],intv)

{//cost为带权有向图的邻接矩阵,v为指定的源点,数据从0开始储存

intdist[N],s[N],rear[N];//dist[i]为当前源点到顶点i的最小距离,s表示相应顶点是否并入集合的标志

intq[N][N];//到i顶点的最短路径存储在队列q[i]中,队头指针为0,队尾指针存储在rear[i]中。

inti,j,k,win,m;

for(i=0;i

{

s[i]=0;

rear[i]=-1;

}

for(i=0;i

{

dist[i]=cost[v][i];

if(dist[i]

{

q[i][++rear[i]]=v;

q[i][++rear[i]]=i;

}

}

s[v]=1;//v并入集合

for(k=0;k

{

win=MAX;j=v;

for(i=1;i

if(s[i]==0&&dist[i]

{

j=i;win=dist[i];}

if(j!

=i)

{

s[j]=1;

printf("\nthe%d'sshortestdistanceis%d\n",j,dist[j]);

for(i=0;i<=rear[j];i++)

printf("%5d",q[j][i]);//打印从源点到j的最短路径

for(i=1;i

if(s[i]==0&&((dist[j]+cost[j][i])

{

dist[i]=dist[j]+cost[j][i];

for(m=0;m<=rear[j];m++)

q[i][m]=q[j][m];//修改相应的路径

rear[i]=rear[j];

q[i][++rear[i]]=i;

}//if

}//if

}//for

}//end

算法6.9

voidfloyed(intgraph[MAX+1][MAX+1],intpath[MAX+1][MAX+1][MAX+1])//下标从1开始

{

inti,j,k,l,n,m;

inta[MAX+1][MAX+1];

for(k=1;k<=MAX;k++)

for(i=1;i<=MAX;i++)

for(j=1;j<=MAX;j++)

path[i][j][k]=0;

for(i=1;i<=MAX;i++)

for(j=1;j<=MAX;j++)

{

if(0!

=graph[i][j])

{

a[i][j]=graph[i][j];

path[i][j][1]=i;

path[i][j][2]=j;

}

else

{

a[i][j]=0;

}

}

for(k=1;k<=MAX;k++)

for(i=1;i<=MAX;i++)

for(j=1;j<=MAX;j++)

{

if(a[i][k]!

=0&&a[k][j]!

=0&&((a[i][k]+a[k][j]

{

a[i][j]=a[i][k]+a[k][j];

for(l=1,m=1,n=2;l<=MAX;l++)

{

if(0!

=path[i][k][m])

{

path[i][j][l]=path[i][k][m];

m++;

}

else

{

if(0!

=path[k][j][n])

{

path[i][j][l]=path[k][j][n];

n++;

}

else

break;

}

}

}

}

}

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

当前位置:首页 > 高等教育 > 理学

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

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