图的所有算法.docx
《图的所有算法.docx》由会员分享,可在线阅读,更多相关《图的所有算法.docx(20页珍藏版)》请在冰豆网上搜索。
图的所有算法
#definetrue1
#definefalse0
#defineok1
#defineerror0
#defineoverflow-2
#definenull0
typedefintstatus;
#include
#include
#include
#definemaxlen10
#definelarge999
typedefstruct
{
inta[maxlen],b[maxlen],h[maxlen];/*第K边的起点,终点,权值*/
charvexs[maxlen];/*顶点信息集合*/
intvexnum,arcnum;/*顶点数和边数*/
intkind;/*图的类型*/
intarcs[maxlen][maxlen];/*邻接矩阵*/
}graph;
typedefstructnode/*表结点结构*/
{
intadjvex;/*存放与头结点相邻接的顶点在数组中的序号*/
intinfo;/*权值*/
structnode*next;/*指向与头结点相邻接下一个顶点的表结点*/
}edgenode;
typedefstruct/*头结点结构*/
{
intid;/*顶点入度*/
chardata;/*顶点信息*/
edgenode*link;/*指向头结点对应的单链表中的表结点*/
}vexnode;
typedefstruct/*邻接表结构*/
{
vexnodeadjs[maxlen];/*邻接表的头结点集合*/
intvexnum,arcnum;/*顶点数,边数*/
intkind;
}adjlist;
typedefstructqnode/*队列存储结构*/
{intdata;
structqnode*next;
}linkqlist;
typedefstruct
{linkqlist*front;/*队头指针*/
linkqlist*rear;/*队尾指针*/
}linkqueue;
typedefstruct/*栈结构*/
{intstack[maxlen];
inttop;
}stackstru;
intcnull=-1;
graphg;
adjlistadjl;
stackstru*t;/*拓扑序列顶点栈*/
stackstru*s;/*零入度顶点栈*/
linkqueue*q;
graphprintf_adjmatrix(graphg)/*输出邻接矩阵*/
{
inti,j;
printf("邻接矩阵:
\n");
printf("vertex\t");
for(i=0;iprintf("\n");
for(i=0;i{printf("%4c\t",g.vexs[i]);
for(j=0;jprintf("\n");
}
returng;
}
voidcreate_1(graphg)
{
inti,j,k,c=0;
for(i=0;ifor(j=0;jg.arcs[i][j]=c;
for(k=0;kg.arcs[g.a[k]-1][g.b[k]-1]=1;
printf_adjmatrix(g);
}
voidcreate_2(graphg)
{
inti,j,k,c=0;
for(i=0;ifor(j=0;jg.arcs[i][j]=c;
for(k=0;k{g.arcs[g.a[k]-1][g.b[k]-1]=1;
g.arcs[g.b[k]-1][g.a[k]-1]=1;
}
printf_adjmatrix(g);
}
graphcreate_3(graphg)
{
inti,j,k,c=999;
for(i=0;ifor(j=0;jg.arcs[i][j]=c;
for(k=0;kg.arcs[g.a[k]-1][g.b[k]-1]=g.h[k];
printf_adjmatrix(g);
returng;
}
graphcreate_4(graphg)
{
inti,j,k,c=999;
for(i=0;ifor(j=0;jg.arcs[i][j]=c;
for(k=0;k{g.arcs[g.a[k]-1][g.b[k]-1]=g.h[k];
g.arcs[g.b[k]-1][g.a[k]-1]=g.h[k];
}
printf_adjmatrix(g);
returng;
}
voidcreategraph(graphg)/*邻接矩阵*/
{
switch(g.kind)
{
case1:
create_1(g);break;
case2:
create_2(g);break;
case3:
create_3(g);break;
case4:
create_4(g);break;
default:
printf("Error\n");
}
}
adjlistcreatelist(graphg,adjlistadjl)/*邻接表*/
{
inti;
edgenode*p;
if(g.kind==1||g.kind==3)
{for(i=0;i{p=(edgenode*)malloc(sizeof(edgenode));
p->adjvex=g.b[i];
p->info=g.h[i];
p->next=adjl.adjs[g.a[i]-1].link;
adjl.adjs[g.a[i]-1].link=p;
}
}
if(g.kind==2||g.kind==4)
{for(i=0;i{p=(edgenode*)malloc(sizeof(edgenode));
p->info=g.h[i];
p->adjvex=g.b[i];
p->next=adjl.adjs[g.a[i]-1].link;
adjl.adjs[g.a[i]-1].link=p;
p=(edgenode*)malloc(sizeof(edgenode));
p->info=g.h[i];
p->adjvex=g.a[i];
p->next=adjl.adjs[g.b[i]-1].link;
adjl.adjs[g.b[i]-1].link=p;
}
}
printf("邻接表为:
\n");
for(i=0;i{printf("[%d,%c]=>",i+1,adjl.adjs[i].data);
p=adjl.adjs[i].link;
while(p!
=cnull)
{printf("[%c,%d]-->",adjl.adjs[(p->adjvex)-1].data,p->info);
p=p->next;
}
printf("^\n");
}
returnadjl;
}
voidinitqueue(linkqueue*p)
{p->front=(linkqlist*)malloc(sizeof(linkqlist));
p->rear=p->front;
(p->front)->next=null;
}
statusempty(linkqueue*q)
{intv;
if(q->front==q->rear)v=true;
elsev=false;
returnv;
}
statusaddqueue(linkqueue*q,inte)/*入队列*/
{
q->rear->next=(linkqlist*)malloc(sizeof(linkqlist));
q->rear=q->rear->next;
if(!
q->rear)return-1;
q->rear->data=e;
q->rear->next=null;
}
statusdelqueue(linkqueue*q)/*出队列*/
{
linkqlist*p;
inte;
if(q->front==q->rear)
printf("thelinklistisoverflow");
elsep=(q->front)->next;
(q->front)->next=p->next;
e=p->data;
if(q->rear==p)
q->rear=q->front;
free(p);/*释放P所指的内存区*/
return(e);
}
voidDFS(inti,adjlistadjl)/*深度优先搜索*/
{edgenode*p;
intj;
intvisited[maxlen];/*访问标志数组,访问过为1,未访问过为0*/
for(j=0;jprintf("%4c->",adjl.adjs[i-1].data);
visited[i-1]=1;
p=adjl.adjs[i-1].link;
while(p!
=cnull)
{if(visited[(p->adjvex)-1]!
=1)DFS((p->adjvex),adjl);
p=p->next;
}
}
voidBFS(inti,adjlistadjl)/*广度优先搜索*/
{edgenode*p;
intj;
intvisited[maxlen];
for(j=0;jinitqueue(q);
printf("%4c->",adjl.adjs[i-1].data);
visited[i-1]=1;
addqueue(q,i);
while(!
empty(q))
{i=delqueue(q);
p=adjl.adjs[i-1].link;
while(p!
=cnull)
{if(visited[(p->adjvex)-1]==0)
{printf("%4c->",adjl.adjs[p->adjvex-1].data);
visited[(p->adjvex)-1]=1;
addqueue(q,p->adjvex);
p=p->next;
}
}
}
}
statusinitstack(stackstru*s)/*构造空栈*/
{s->top=0;
returnok;
}
statuspush(stackstru*s,intx)/*入栈*/
{if(s->top==maxlen)
printf("thestackisoverflow!
\n");
else{s->top=s->top+1;
s->stack[s->top]=x;
}
}
statuspop(stackstru*s)
{inty;
if(s->top==0)printf("thestackisempty!
\n");
else{y=s->stack[s->top];
s->top=s->top-1;
}
returny;
}
statusstackempty(stackstru*s)
{if(s->top==maxlen)return(true);
elsereturn(false);
}
statustopsort(adjlistadjl)/*拓扑排序*/
{
inti,k,count;
edgenode*p;
printf("拓扑排序序列为:
\n");
initstack(s);
for(i=0;iif(adjl.adjs[i].id==0)push(s,adjl.adjs[i].data);
count=0;
while(!
stackempty(s))
{i=pop(s);
printf("%4c->",adjl.adjs[i].data);
++count;
for(p=adjl.adjs[i].link;p;p=p->next)
{k=p->adjvex;
if(!
(--adjl.adjs[k-1].id))push(s,k-1);
}
}
if(count{printf("\n网中有环!
\n");/*拓扑排序输出的顶点数<图中的顶点数*/
returnerror;
}
elsereturnok;
}
voidprim(graphg)/*最小生成树*/
{
inti,j,k,min;
intlowcost[maxlen];/*权值*/
intcloset[maxlen];/*最小生成树结点*/
printf("最小生成树的边为:
\n");
for(i=1;i{
lowcost[i]=g.arcs[0][i];
closet[i]=1;
}
closet[1]=0;
j=1;
for(i=1;i{
min=lowcost[j];
k=i;
for(j=1;jif(lowcost[j]=0)
{
min=lowcost[j];
k=j;
}
printf("(%c,%c),",g.vexs[k-1],g.vexs[closet[k-1]]);
closet[k]=0;
for(j=1;jif(g.arcs[k][j]=0)
{
lowcost[j]=g.arcs[k][j];
closet[j]=k;
}
}
}
intve[maxlen];/*最早发生时间*/
intvl[maxlen];/*最迟发生时间*/
statustoporder(adjlistadjl,stackstru*t)/*求各顶点事件的最早发生时间ve*/
{inti,j,count,k;
edgenode*p;
initstack(s);
initstack(t);
for(i=0;iif(adjl.adjs[i].id==0)push(s,i);
count=0;
for(i=0;iwhile(!
stackempty(s))
{j=pop(s);push(t,j);++count;
for(p=adjl.adjs[j].link;p;p=p->next)
{k=p->adjvex;
if(--adjl.adjs[k-1].id==0)push(s,k-1);
if(ve[j]+(p->info)>ve[k-1])ve[k-1]=ve[j]+(p->info);
}
}
if(countelsereturnok;
}
statuscriticalpath(adjlistadjl)/*关键路径*/
{inti,j,k,dut,ee,el;
edgenode*p;
if(!
toporder(adjl,t))returnerror;
for(i=0;iprintf("关键路径为:
\n");
while(!
stackempty(t))/*按拓扑排序的逆序求各顶点的最迟发生时间ve值*/
for(j=pop(t),p=adjl.adjs[j].link;p;p=p->next)
{k=p->adjvex;dut=(p->info);
if(vl[k]-dut}
for(j=0;jfor(p=adjl.adjs[j].link;p;p=p->next)
{k=p->adjvex;dut=p->info;
ee=ve[j];el=vl[k-1]-dut;
if(ee==el)printf("(%c,%c)->",adjl.adjs[j].data,adjl.adjs[k-1].data);
}
}
voidshortpath_dijkstra(graphg)
{intcost[maxlen][maxlen];
intdist[maxlen];/*某源点到各顶点的最短路径长度*/
intpath[maxlen];/*某源点到终点经过的顶点集合的数组*/
ints[maxlen];/*最短路径的终点集合*/
inti,j,n,v0,min,u;/*U存放最短路径的终点*/
printf("\n请输入起点的编号:
");
scanf("%d",&v0);
v0--;
for(i=0;i{for(j=0;jcost[i][j]=g.arcs[i][j];
}
for(i=0;i{dist[i]=cost[v0][i];
if(dist[i]0)path[i]=v0;
s[i]=0;
}
s[v0]=1;
for(i=0;i{min=large;
u=v0;
for(j=0;jif(s[j]==0&&dist[j]{min=dist[j];u=j;}
s[u]=1;/*U顶点是求得最短路径的顶点编号*/
for(j=0;jif(s[j]==0&&dist[u]+cost[u][j]{dist[j]=dist[u]+cost[u][j];
path[j]=u;
}
}
printf("\n顶点%d到各顶点的最短路径长度为:
\n",v0);
for(i=0;iif(s[i]==1)
{u=i;
while(u!
=v0)
{printf("%4c<-",g.vexs[u]);
u=path[u];
}
printf("%4c",g.vexs[u]);
printf(":
%d\n",path[i]);
}
elseprintf("%4c<-%4c:
无路径\n",g.vexs[i],g.vexs[v0]);
}
voidshortpath_floyd(graphg)
{intpath[maxlen][maxlen];
intshort3[maxlen][maxlen];/*权值*/
inti,j,k;
for(i=0;ifor(j=0;j{short3[i][j]=g.arcs[i][j];
path[i][j]=0;
}
printf("\n各顶点间的最短路径为:
\n");
for(k=0;kfor(i=0;i{if(short3[i][j]>(short3[i][k]+short3[k][j]))
{short3[i][j]=short3[i][k]+short3[k][j];
path[i][j]=k;
}
printf("(%4c->%4c):
%d",g.vexs[i-1],g.vexs[j-1],short3[i][j]);
}
}
main()
{
inta,i,j,k,h;
printf("\n请输入图的类型(1:
有向图2:
无向图3:
有向网4:
无向网):
");
scanf("%d",&i);
{g.kind=i;adjl.kind=i;}
printf("请输入顶点数,边数:
");
scanf("%d,%d",&i,&j);
g.vexnum=i;adjl.vexnum=i;
g.arcnum=j;adjl.arcnum=j;
for(i=0;i{printf("第%d个顶点的信息:
",i+1);
scanf("%s",&g.vexs[i]);
adjl.adjs[i].data=g.vexs[i];
adjl.adjs[i].link=cnull;
adjl.adjs[i].id=0;
}
for(k=1;k<=g.arcnum;k++)
{label:
if(g.kind==1||g.kind==3)
printf("第%d条边的起点编号,终点编号:
",k);
elseprintf("第%d条边的两个顶点的编号:
",k);
scanf("%d,%d",&i,&j);
g.a[k-1]=i;g.b[k-1]=j;
while(i<1||i>g.vexnum||j<1||j>g.vexnum)
{printf("编号超出范围,重新输入");gotolabel;
}
if(g.kind==3||g.kind==4)
{printf("\t该边的权值:
");
scanf("%d",&h);
g.h[k-1]=h;
}
elseg.h[k-