您的位置:首页 > 其它

图转换为树-最小生成树

2015-12-27 21:47 363 查看
利用prims和kruskal两种方法实现最小生成树。

直接上code吧。记录下

#include <stdio.h>
#include <stdlib.h>

#define MAX 10
#define VertexNum 5

struct List
{
int v1;
int v2;
int weight;
int marked;
struct List *next;
};

typedef struct List* Edge;

int g_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}
};
int g_kruskal_visited[MAX] = {0};

int g_prims_visited[MAX] = {0};

void mst_print_edge(Edge Head)
{
Edge pointer;
pointer = Head;
while(pointer!=NULL)
{
printf("[%d,%d] (%d)",pointer->v1, pointer->v2, pointer->weight);
pointer = pointer->next;
}
printf("\n");
}

void mst_free_edge(Edge Head)
{
Edge pointer;

while(Head!=NULL)
{
pointer = Head;
Head = Head->next;
free(pointer);
}
}

Edge mst_insert_edge(Edge Head, Edge New)
{
Edge pointer = Head;
while(1)
{
if (New->weight < Head->weight)
{
/*插入在首节点之前*/
New->next = Head;
Head=New;
break;
}
else if (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;
}

Edge mst_create_edge(Edge Head)
{
Edge New;
Edge pointer;
int i;
Head = (Edge)malloc(sizeof(struct List));
if (Head == NULL)
printf("malloc failed\n");
else
{
Head->v1 = g_Edges[0][0];
Head->v2 = g_Edges[0][1];
Head->weight = g_Edges[0][2];
Head->marked = 0;
Head->next = NULL;

for(i = 1; i < MAX; i++)
{
New = (Edge)malloc(sizeof(struct List));
if (New)
{
New->v1 = g_Edges[i][0];
New->v2 = g_Edges[i][1];
New->weight = g_Edges[i][2];
New->marked = 0;
New->next = NULL;

Head = mst_insert_edge(Head, New);

}
}
}
return Head;
}

void mst_kruskal(Edge Head)
{
Edge pointer;
int EdgeNum = 0;
int weight = 0;

pointer = Head;

while (EdgeNum != (VertexNum-1))
{
if (g_kruskal_visited[pointer->v1] == 0 || g_kruskal_visited[pointer->v2] == 0)
{
printf("==>[%d %d %d] ", pointer->v1, pointer->v2, pointer->weight);
weight += pointer->weight;
EdgeNum++;
g_kruskal_visited[pointer->v1] = 1;
g_kruskal_visited[pointer->v2] = 1;
}
pointer = pointer->next;
if (pointer == NULL)
{
printf("No Spanning Tree\n");
break;
}
}
printf("\nTotal weight = %d\n", weight);
}

void mst_prims(Edge Head, int index)
{
Edge pointer;
Edge MinEdge;
int EdgeNum = 0;
int weight = 0;
g_prims_visited[index] = 1;
int i = 0;
while (EdgeNum != (VertexNum-1))
{
int MinEdge_weight = 100000;
for (i = 1; i <= VertexNum; i++)
{
pointer = Head;
if (g_prims_visited[i] == 1)
{
/*已经在生成树的集合中*/

while(pointer->marked == 1)
{
if (pointer->next == NULL)
break;
pointer = pointer->next;

}

while(pointer!=NULL)
{
/*如果两顶点都在生成树集合中, 表示是已经查找过的边*/
//printf("check edge [%d %d %d] MinEdge weight %d\n",
// pointer->v1, pointer->v2, pointer->weight, MinEdge_weight);
if (g_prims_visited[pointer->v1] == 1 && g_prims_visited[pointer->v2] == 1)
pointer->marked = 1;

if (MinEdge_weight > pointer->weight &&
pointer->marked == 0 &&
(pointer->v1 == i || pointer->v2 == i))
{
MinEdge_weight = pointer->weight;
MinEdge = pointer;
printf("Min Edge [%d %d %d]\n", MinEdge->v1, MinEdge->v2, MinEdge->weight);
}

pointer = pointer->next;
}
printf("----\n");
}
}
g_prims_visited[MinEdge->v1] = 1;
g_prims_visited[MinEdge->v2] = 1;
EdgeNum++;
weight += MinEdge->weight;
printf("\t\t\t==>[%d %d %d]\n", MinEdge->v1, MinEdge->v2, MinEdge->weight);
}
printf("\nprims Total weight = %d\n", weight);
}

int main(int argc, char **argv)
{
Edge Head = NULL;
int i;
Head = mst_create_edge(Head);
if (Head)
{
printf("Kruskal Algo:\n");
mst_print_edge(Head);
mst_kruskal(Head);
printf("Prims Algo:\n");
mst_prims(Head, 5);
mst_free_edge(Head);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: