Kruskal(克鲁斯卡尔)算法
#include "graph.cpp"
#define MaxSize 100
typedef struct
{
int u;
int v;
int w;
} Edge;
void InsertSort(Edge E[],int n)
{
int i,j;
Edge temp;
for (i=1;i<n;i++)
{
temp=E[i];
j=i-1;
while (j>=0 && temp.w<E[j].w)
{
E[j+1]=E[j];
j--;
}
E[j+1]=temp;
}
}
void Kruskal(MatGraph g)
{
int i,j,u1,v1,sn1,sn2,k;
int vset[MAXV];
Edge E[MaxSize];
k=0;
for (i=0;i<g.n;i++)
for (j=0;j<=i;j++)
{
if (g.edges[i][j]!=0 && g.edges[i][j]!=INF)
{
E[k].u=i;E[k].v=j;E[k].w=g.edges[i][j];
k++;
}
}
InsertSort(E,g.e);
for (i=0;i<g.n;i++)
vset[i]=i;
k=1;
j=0;
while (k<g.n)
{
u1=E[j].u;v1=E[j].v;
sn1=vset[u1];
sn2=vset[v1];
if (sn1!=sn2)
{
printf(" (%d,%d):%d\n",u1,v1,E[j].w);
k++;
for (i=0;i<g.n;i++)
if (vset[i]==sn2)
vset[i]=sn1;
}
j++;
}
}
int main()
{
MatGraph g;
int A[MAXV][MAXV]={
{0,28,INF,INF,INF,10,INF},
{28,0,16,INF,INF,INF,14},
{INF,16,0,12,INF,INF,INF},
{INF,INF,12,0,22,INF,18},
{INF,INF,INF,22,0,25,24},
{10,INF,INF,INF,25,0,INF},
{INF,14,INF,18,24,INF,0}};
int n=7, e=9;
CreateMat(g,A,n,e);
printf("图G的邻接矩阵:\n");
DispMat(g);
printf("Kruskal算法结果\n");
Kruskal(g);
return 1;
}
改进的Kruskal(克鲁斯卡尔)算法
#include "graph.cpp"
#define MaxSize 100
typedef struct
{
int u;
int v;
int w;
} Edge;
typedef struct node
{
int rank;
int parent;
} UFSTree;
void MAKE_SET(UFSTree t[],int n)
{
int i;
for (i=0;i<n;i++)
{
t[i].rank=0;
t[i].parent=i;
}
}
int FIND_SET(UFSTree t[],int x)
{
if (x!=t[x].parent)
return(FIND_SET(t,t[x].parent));
else
return(x);
}
void UNION(UFSTree t[],int x,int y)
{
x=FIND_SET(t,x);
y=FIND_SET(t,y);
if (t[x].rank>t[y].rank)
t[y].parent=x;
else
{
t[x].parent=y;
if (t[x].rank==t[y].rank)
t[y].rank++;
}
}
void sift(Edge E[],int low,int high)
{
int i=low,j=2*i;
Edge temp=E[i];
while (j<=high)
{
if (j<high && E[j].w<E[j+1].w)
j++;
if (temp.w<E[j].w)
{
E[i]=E[j];
i=j;
j=2*i;
}
else break;
}
E[i]=temp;
}
void HeapSort(Edge E[],int n)
{
int i;
Edge temp;
for (i=n/2;i>=1;i--)
sift(E,i,n);
for (i=n;i>=2;i--)
{
temp=E[1];
E[1]=E[i];
E[i]=temp;
sift(E,1,i-1);
}
}
void Kruskal(MatGraph g)
{
int i,j,k,u1,v1,sn1,sn2;
UFSTree t[MaxSize];
Edge E[MaxSize];
k=1;
for (i=0;i<g.n;i++)
for (j=0;j<=i;j++)
if (g.edges[i][j]!=0 && g.edges[i][j]!=INF)
{
E[k].u=i;E[k].v=j;E[k].w=g.edges[i][j];
k++;
}
HeapSort(E,g.e);
MAKE_SET(t,g.n);
k=1;
j=1;
while (k<g.n)
{
u1=E[j].u;
v1=E[j].v;
sn1=FIND_SET(t,u1);
sn2=FIND_SET(t,v1);
if (sn1!=sn2)
{
printf(" (%d,%d):%d\n",u1,v1,E[j].w);
k++;
UNION(t,u1,v1);
}
j++;
}
}
int main()
{
MatGraph g;
int A[MAXV][MAXV]={
{0,28,INF,INF,INF,10,INF},
{28,0,16,INF,INF,INF,14},
{INF,16,0,12,INF,INF,INF},
{INF,INF,12,0,22,INF,18},
{INF,INF,INF,22,0,25,24},
{10,INF,INF,INF,25,0,INF},
{INF,14,INF,18,24,INF,0}};
int n=7, e=9;
CreateMat(g,A,n,e);
printf("图G的邻接矩阵:\n");
DispMat(g);
printf("Kruskal算法结果\n");
Kruskal(g);
return 1;
}
Dijkstra(迪杰斯特拉)算法
#include "graph.cpp"
int count=0;
void Dispath(MatGraph g,int dist[],int path[],int S[],int v)
{ int i,j,k;
int apath[MAXV],d;
for (i=0;i<g.n;i++)
if (S[i]==1 && i!=v)
{ printf(" 从顶点%d到顶点%d的路径长度为:%d\t路径为:",v,i,dist[i]);
d=0; apath[d]=i;
k=path[i];
if (k==-1)
printf("无路径\n");
else
{ while (k!=v)
{ d++; apath[d]=k;
k=path[k];
}
d++; apath[d]=v;
printf("%d",apath[d]);
for (j=d-1;j>=0;j--)
printf(",%d",apath[j]);
printf("\n");
}
}
}
void disp(int dist[MAXV],int path[MAXV],int n)
{
int i;
printf(" dist path\n");
for (i=0;i<n;i++)
if (dist[i]!=INF)
printf("%4d",dist[i]);
else
printf("%4s","∞");
printf("\t");
for (i=0;i<n;i++)
printf("%4d",path[i]);
printf("\n");
}
void Dijkstra(MatGraph g,int v)
{ int dist[MAXV],path[MAXV];
int S[MAXV];
int Mindis,i,j,u;
bool flag;
for (i=0;i<g.n;i++)
{ dist[i]=g.edges[v][i];
S[i]=0;
if (g.edges[v][i]<INF)
path[i]=v;
else
path[i]=-1;
}
disp(dist,path,g.n);
printf("(%d)将顶点%d添加到S集合\n",++count,v);
S[v]=1;path[v]=0;
for (i=0;i<g.n-1;i++)
{ Mindis=INF;
for (j=0;j<g.n;j++)
if (S[j]==0 && dist[j]<Mindis)
{ u=j;
Mindis=dist[j];
}
printf(" 求出U中最小的顶点%d\n",u);
printf("(%d)将顶点%d添加到S集合\n",++count,u);
S[u]=1;
flag=false;
for (j=0;j<g.n;j++)
if (S[j]==0)
{
if (g.edges[u][j]<INF)
{
flag=true;
printf(" 考虑顶点%d的邻接点%d:",u,j);
if (dist[u]+g.edges[u][j]<dist[j])
{
dist[j]=dist[u]+g.edges[u][j];
printf("修改其最短路径长度dist[%d]为%d,",j,dist[j]);
path[j]=u;
printf("修改最短路径path[%d]为%d\n",j,u);
}
else
printf("顶点%d的最短路径长度没有修改\n",j);
}
}
if (!flag)
printf(" 顶点%d没有未考虑的邻接点(不修改)\n",u);
disp(dist,path,g.n);
}
Dispath(g,dist,path,S,v);
}
int main()
{
MatGraph g;
int A[MAXV][MAXV]={
{0, 6, INF,INF,2},
{INF,0, INF,INF,INF},
{INF,1, 0, 3, INF},
{2, INF,INF,0, INF},
{INF,3, 1, 3, 0}
};
int n=5, e=8;
CreateMat(g,A,n,e);
printf("图G的邻接矩阵:\n");
DispMat(g);
int v=0;
printf("从%d顶点出发的最短路径求解过程如下:\n",v);
Dijkstra(g,v);
return 1;
}
拓扑排序算法
#include "graph.cpp"
void TopSort(AdjGraph *G)
{ int i,j;
int St[MAXV],top=-1;
ArcNode *p;
for (i=0;i<G->n;i++)
G->adjlist[i].count=0;
for (i=0;i<G->n;i++)
{ p=G->adjlist[i].firstarc;
while (p!=NULL)
{ G->adjlist[p->adjvex].count++;
p=p->nextarc;
}
}
for (i=0;i<G->n;i++)
if (G->adjlist[i].count==0)
{ top++;
St[top]=i;
}
while (top>-1)
{ i=St[top];top--;
printf("%d ",i);
p=G->adjlist[i].firstarc;
while (p!=NULL)
{ j=p->adjvex;
G->adjlist[j].count--;
if (G->adjlist[j].count==0)
{ top++;
St[top]=j;
}
p=p->nextarc;
}
}
}
int main()
{
AdjGraph *G;
int A[MAXV][MAXV]=
{{0,1,INF,INF,INF,INF},
{INF,0,1,INF,INF,INF},
{INF,INF,0,1,INF,INF},
{INF,INF,INF,0,INF,INF},
{INF,1,INF,INF,0,1},
{INF,INF,INF,1,INF,0}};
int n=6, e=6;
CreateAdj(G,A,n,e);
printf("图G的邻接表:\n");
DispAdj(G);
printf("拓扑序列:");TopSort(G);printf("\n");
DestroyAdj(G);
return 1;
}
求关键路径算法
#include "graph.cpp"
typedef struct
{ int ino;
int eno;
} KeyNode;
bool TopSort(AdjGraph *G,int topseq[])
{
int i,j,n=0;
int st[MAXV];
int top=-1;
ArcNode *p;
for (i=0;i<G->n;i++)
G->adjlist[i].count=0;
for (i=0;i<G->n;i++)
{ p=G->adjlist[i].firstarc;
while (p!=NULL)
{ G->adjlist[p->adjvex].count++;
p=p->nextarc;
}
}
for (i=0;i<G->n;i++)
if (G->adjlist[i].count==0)
{ top++;
st[top]=i;
}
while (top>-1)
{ i=st[top];top--;
topseq[n]=i; n++;
p=G->adjlist[i].firstarc;
while (p!=NULL)
{ j=p->adjvex;
G->adjlist[j].count--;
if (G->adjlist[j].count==0)
{ top++;
st[top]=j;
}
p=p->nextarc;
}
}
if (n<G->n)
return false;
else
{
printf("拓扑序列:");
for (i=0;i<n;i++)
printf("%c ",(char)(topseq[i]+'A'));
printf("\n");
return true;
}
}
bool KeyPath(AdjGraph *G,int &inode,int &enode,KeyNode keynode[],int &d)
{ int topseq[MAXV];
int i,w;
ArcNode *p;
if (!TopSort(G,topseq))
return false;
inode=topseq[0];
enode=topseq[G->n-1];
int ve[MAXV];
int vl[MAXV];
for (i=0;i<G->n;i++) ve[i]=0;
for (i=0;i<G->n;i++)
{ p=G->adjlist[i].firstarc;
while (p!=NULL)
{ w=p->adjvex;
if (ve[i]+p->weight>ve[w])
ve[w]=ve[i]+p->weight;
p=p->nextarc;
}
}
for (i=0;i<G->n;i++)
vl[i]=ve[enode];
for (i=G->n-2;i>=0;i--)
{ p=G->adjlist[i].firstarc;
while (p!=NULL)
{ w=p->adjvex;
if (vl[w]-p->weight<vl[i])
vl[i]=vl[w]-p->weight;
p=p->nextarc;
}
}
d=-1;
for (i=0;i<G->n;i++)
{ p=G->adjlist[i].firstarc;
while (p!=NULL)
{ w=p->adjvex;
if (ve[i]==vl[w]-p->weight)
{
d++; keynode[d].ino=i; keynode[d].eno=w;
}
p=p->nextarc;
}
}
return true;
}
void DispKeynode(AdjGraph *G)
{
int inode,enode,d,i;
KeyNode keynode[MAXV];
if (KeyPath(G,inode,enode,keynode,d))
{
printf("从源点%c到汇点%c的关键活动:",char(inode='A'),char(enode+'A'));
for (i=0;i<=d;i++)
printf("(%c,%c) ",char(keynode[i].ino+'A'),char(keynode[i].eno+'A'));
printf("\n");
}
else printf("不能求关键活动\n");
}
int main()
{
AdjGraph *G;
int n=9,e=11;
int A[MAXV][MAXV]={
{ 0, 6, 4, 5 ,INF,INF,INF,INF,INF},
{INF, 0, INF,INF, 1 ,INF,INF,INF,INF},
{INF,INF, 0 ,INF, 1 ,INF,INF,INF,INF},
{INF,INF,INF, 0 ,INF,INF,INF, 2 ,INF},
{INF,INF,INF,INF, 0 , 9 , 7 ,INF,INF},
{INF,INF,INF,INF,INF, 0 ,INF,INF, 2 },
{INF,INF,INF,INF,INF,INF, 0 ,INF, 4 },
{INF,INF,INF,INF,INF,INF,INF, 0 , 4 },
{INF,INF,INF,INF,INF,INF,INF,INF, 0 }};
printf("建立图的邻接表:\n");
CreateAdj(G,A,n,e);
printf("图G的邻接表:\n"); DispAdj(G);
DispKeynode(G);
DestroyAdj(G);
return 1;
}