算法导论 最小生成树MST-KRUSKAL

#include 
#include 

//用于边排序和结果集合
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;ivn;i++)
	{
		g->E[i]=(int*)malloc(g->vn*sizeof(int));
	}
	for(int i=0;ivn;i++)
	{
		for(int j=0;jvn;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;ien;i++)
	{
		g->ESort[i]=(pEdgeSortNode)malloc(sizeof(EdgeSortNode));
	}
	int t=0;
	for(int i=0;ivn;i++)
	{
		for(int j=i;jvn;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;jw=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;ien;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%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;ivn;i++)
	{
		pSetNode setNode=makeset(i);
		g->V[i]->snode=setNode;//图中的节点要和森林节点建立联系
	}
	quickSort(g->ESort,0,g->en-1);
	//MST-KRUSKAL核心步骤,利用割理论将安全边一条一条加入结果集合
	for(int i=0;ien;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();
}

你可能感兴趣的:(算法导论)