1、Kruskal算法
#include <stdio.h>
#include <stdlib.h>
struct list
{
int vertex1;
int vertex2;
int weight;
struct list *next;
};
typedef struct list *edge;
#define vertexmax 6 //从下标1存入5点(1~5)
#define edgenum 10 //边数
int visit[vertexmax]; //标记某顶点是否被访问
int Edges[10][3] = /* 输入数据 */
{ {1,2,7}, {1,3,6}, {1,4,5}, {1,5,12}, {2,3,14},
{2,4,8}, {2,5,8}, {3,4,3}, {3,5,9}, {4,5,2} };
edge creategraph(edge head) //按边权重排序各边,生成链表
{
int i;
edge New,pointer;
for(i=1;i<edgenum;i++)
{
New=(edge)malloc(sizeof(struct list));
pointer=head;
New->vertex1=Edges[i][0];
New->vertex2=Edges[i][1];
New->weight=Edges[i][2];
New->next=NULL;
while(pointer!=NULL)
{
if(New->weight<head->weight)
{
New->next=head;
head=New;
break;
}
if(New->weight>=pointer->weight && pointer->next==NULL)
{
pointer->next=New;
break;
}
if(New->weight>=pointer->weight && New->weight<pointer->next->weight)
{
New->next=pointer->next;
pointer->next=New;
break;
}
pointer=pointer->next;
}
}
return head;
}
void print(edge head) //打印链表
{
edge pointer=head;
while(pointer!=NULL)
{
printf("(%d,%d)[%d]",pointer->vertex1,pointer->vertex2,pointer->weight);
pointer=pointer->next;
}
printf("\n");
}
void Krusral(edge head) //krusral算法
{
int minedgenum=0;
int weight=0;
edge pointer=head;
while(pointer!=NULL)
{
if(visit[pointer->vertex1]==0 || visit[pointer->vertex2]==0) //当边的两端点有一个未访问时
{
printf("(%d%d)[%d] ",pointer->vertex1,pointer->vertex2,pointer->weight);
weight=weight+pointer->weight;
visit[pointer->vertex1]=1;
visit[pointer->vertex2]=1;
minedgenum++;
}
if(minedgenum==vertexmax-2) //生产树的变数等于(顶点数-1)时,结束
{
printf("\nthe sum of the weight is %d\n",weight);
break;
}
pointer=pointer->next;
}
}
void main()
{
edge head;
int i;
for(i=0;i<vertexmax;i++)
{
visit[i]=0;
}
head=(edge)malloc(sizeof(struct list));
if(head!=NULL)
{
head->vertex1=1;
head->vertex2=2;
head->weight=7;
head->next=NULL;
head=creategraph(head);
print(head);
Krusral(head);
}
system("pause");
}
2、Prims算法
#include <stdio.h>
#include <stdlib.h>
struct list
{
int vertex1;
int vertex2;
int weight;
int flag;
struct list *next;
};
struct node
{
int index;
struct list *next;
};
typedef struct list *edge;
typedef struct node *Node;
#define vertexmax 6 //从下标1存入5点(1~5)
#define edgenum 10 //边数
struct node head[vertexmax];
int visit[vertexmax]; //标记某顶点是否被访问
int Edges[10][3] = /* 输入数据 */
{ {1,2,7}, {1,3,6}, {1,4,5}, {1,5,12}, {2,3,14},
{2,4,8}, {2,5,8}, {3,4,3}, {3,5,9}, {4,5,2} };
void creategraph(Node head) //按边权重排序各边,生成链表
{
int i,j;
edge pointer,New;
for(i=1;i<vertexmax;i++)
{
for(j=0;j<edgenum;j++)
{
pointer=head[i].next;
if(Edges[j][0]==i)
{
New=(edge)malloc(sizeof(struct list));
New->flag=0;
New->vertex1=Edges[j][0];
New->vertex2=Edges[j][1];
New->weight=Edges[j][2];
New->next=NULL;
/* while(pointer!=NULL)
{
pointer=pointer->next;
}*/
New->next=pointer;
head[i].next=New;
}
}
}
}
void print(Node head) //打印链表
{
edge pointer;
int i;
for(i=1;i<vertexmax;i++)
{
pointer=head[i].next;
while(pointer!=NULL)
{
printf("(%d,%d)",pointer->vertex1,pointer->vertex2);
pointer=pointer->next;
}
if(i==vertexmax-1)
break;
printf("\n");
}
}
void prims(Node head,int index) //krusral算法
{
int i;
int vertex2;
int minedgenum=1;
edge pointer,minedge;
visit[index]=1;
while(minedgenum<=vertexmax-2)
{
minedge=(edge)malloc(sizeof(struct list));
minedge->weight=999;
for(i=1;i<vertexmax;i++)
{
pointer=head[i].next;
if(pointer==NULL)
continue;
else
{
do
{
if((pointer->flag==0) && (minedge->weight > pointer->weight)
//visit[pointer->v1和v2]只能有一个被访问过
&& (visit[pointer->vertex1]==1^visit[pointer->vertex2]==1)
&&(pointer->vertex1==i || pointer->vertex2==i))
{
minedge=pointer;
vertex2=minedge->vertex2;
}
pointer=pointer->next;
}while(pointer!=NULL);
}
}
printf("(%d,%d) ",minedge->vertex1,minedge->vertex2);
visit[minedge->vertex1]=1;
visit[minedge->vertex2]=1;
minedgenum++;
minedge->flag=1;
}
printf("\n");
}
void main()
{
int i;
for(i=0;i<vertexmax;i++)
{
visit[i]=0;
}
for(i=0;i<vertexmax;i++)
{
head[i].index=i;
head[i].next=NULL;
}
creategraph(head);
print(head);
printf("the min tree is counstructed by the edges: ");
prims(head,1);
system("pause");
}