#include <stdio.h>
#include <stdlib.h>
//用于边排序和结果集合
typedef struct
{
int u;
int v;
int w;
}EdgeSortNode,*pEdgeSortNode;
//用于不相交森林
typedef struct SN
{
int vi;
struct SN* p;
int rank;
}SetNode,*pSetNode;
//图节点
typedef struct
{
char name;
pSetNode snode;
}Vertex,*pVertex;
//图
typedef struct
{
int vn;
int en;
int **E;
pVertex *V;
pEdgeSortNode *ESort;
}Graph,*pGraph;
//根据算法导论 图23-4 初始化图
pGraph initGraph()
{
pGraph g=(pGraph)malloc(sizeof(Graph));
g->vn=9;
g->en=14;
pVertex va=(pVertex)malloc(sizeof(Vertex));
va->name='a';
va->snode=NULL;
pVertex vb=(pVertex)malloc(sizeof(Vertex));
vb->name='b';
vb->snode=NULL;
pVertex vc=(pVertex)malloc(sizeof(Vertex));
vc->name='c';
vc->snode=NULL;
pVertex vd=(pVertex)malloc(sizeof(Vertex));
vd->name='d';
vd->snode=NULL;
pVertex ve=(pVertex)malloc(sizeof(Vertex));
ve->name='e';
ve->snode=NULL;
pVertex vf=(pVertex)malloc(sizeof(Vertex));
vf->name='f';
vf->snode=NULL;
pVertex vg=(pVertex)malloc(sizeof(Vertex));
vg->name='g';
vg->snode=NULL;
pVertex vh=(pVertex)malloc(sizeof(Vertex));
vh->name='h';
vh->snode=NULL;
pVertex vi=(pVertex)malloc(sizeof(Vertex));
vi->name='i';
vi->snode=NULL;
g->V=(pVertex*)malloc(g->vn*sizeof(pVertex));
g->V[0]=va;
g->V[1]=vb;
g->V[2]=vc;
g->V[3]=vd;
g->V[4]=ve;
g->V[5]=vf;
g->V[6]=vg;
g->V[7]=vh;
g->V[8]=vi;
g->E = (int**)malloc(g->vn*sizeof(int*));
for(int i=0;i<g->vn;i++)
{
g->E[i]=(int*)malloc(g->vn*sizeof(int));
}
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
g->E[i][j]=0;
}
}
g->E[0][1]=g->E[1][0]=4;
g->E[1][2]=g->E[2][1]=8;
g->E[2][3]=g->E[3][2]=7;
g->E[3][4]=g->E[4][3]=9;
g->E[4][5]=g->E[5][4]=10;
g->E[5][6]=g->E[6][5]=2;
g->E[6][7]=g->E[7][6]=1;
g->E[0][7]=g->E[7][0]=8;
g->E[2][5]=g->E[5][2]=4;
g->E[3][5]=g->E[5][3]=14;
g->E[6][8]=g->E[8][6]=6;
g->E[7][8]=g->E[8][7]=7;
g->E[2][8]=g->E[8][2]=2;
g->E[1][7]=g->E[7][1]=11;
g->ESort = (pEdgeSortNode*)malloc(sizeof(pEdgeSortNode));
for(int i=0;i<g->en;i++)
{
g->ESort[i]=(pEdgeSortNode)malloc(sizeof(EdgeSortNode));
}
int t=0;
for(int i=0;i<g->vn;i++)
{
for(int j=i;j<g->vn;j++)
{
if(g->E[i][j]>0)
{
g->ESort[t]->u=i;
g->ESort[t]->v=j;
g->ESort[t]->w=g->E[i][j];
t++;
}
}
}
return g;
}
//-----------快速排序开始---------------------
void swop(pEdgeSortNode *a,pEdgeSortNode *b)
{
pEdgeSortNode temp=(*a);
(*a)=(*b);
(*b)=temp;
}
int partition(pEdgeSortNode *esort,int p,int q)
{
int i=p-1;
int w=esort[q]->w;
for(int j=i+1;j<q;j++)
{
if(esort[j]->w<w)
{
i++;
swop(&(esort[i]),&(esort[j]));
}
}
swop(&(esort[i+1]),&(esort[q]));
return i+1;
}
void quickSort(pEdgeSortNode *esort,int p,int q)
{
if(p>=q)
return;
int r=partition(esort,p,q);
quickSort(esort,p,r-1);
quickSort(esort,r+1,q);
}
//-----------快速排序结束---------------------
void printEW(pGraph g)
{
for(int i=0;i<g->en;i++)
{
printf("%d ",g->ESort[i]->w);
}
printf("\n");
}
//-------------不相交森林开始-----------------
pSetNode makeset(int i)
{
pSetNode setNode=(pSetNode)malloc(sizeof(SetNode));
setNode->p=setNode;
setNode->rank=0;
setNode->vi=i;
return setNode;
}
void link(pSetNode x,pSetNode y)
{
if(x->rank>y->rank)
y->p=x;
else
{
x->p=y;
if(x->rank==y->rank)
y->rank++;
}
}
pSetNode findSet(pSetNode x)
{
if(x != x->p)
x->p=findSet(x->p);
return x->p;
}
void unionSet(pSetNode x,pSetNode y)
{
link(findSet(x),findSet(y));
}
//-------------不相交森林结束-----------------
void printA(pEdgeSortNode*A,int len)
{
for(int i=0;i<len;i++)
{
printf("%d->%d,%d\n",A[i]->u,A[i]->v,A[i]->w);
}
}
void main()
{
pGraph g=initGraph();
//A是最后的结果集合,ai保存A的序列号
pEdgeSortNode *A=(pEdgeSortNode*)malloc(g->en*sizeof(EdgeSortNode));
int ai=0;
for(int i=0;i<g->vn;i++)
{
pSetNode setNode=makeset(i);
g->V[i]->snode=setNode;//图中的节点要和森林节点建立联系
}
quickSort(g->ESort,0,g->en-1);
//MST-KRUSKAL核心步骤,利用割理论将安全边一条一条加入结果集合
for(int i=0;i<g->en;i++)
{
pEdgeSortNode pe=g->ESort[i];
pSetNode u=g->V[pe->u]->snode;
pSetNode v=g->V[pe->v]->snode;
pSetNode up=findSet(u);
pSetNode vp=findSet(v);
if(up!=vp)
{
A[ai]=pe;
ai++;
unionSet(u,v);
}
}
printA(A,ai);
getchar();
}
算法导论 最小生成树MST-KRUSKAL
最新推荐文章于 2024-11-29 17:46:49 发布