无向数据网的最小代价生成树:Prim算法

额,教科书上的案例是错误的,Prim算法没有那么简单,短短的几行代码根本实现不了。不过仍然向它致敬,因为理论讲的很透彻,我也是根据理论写出来这个复杂代码的,本算法的基本数据结构是邻接表。
Prim算法简介:(这里转载网友的介绍~)
最小生成树问题的概念—普里姆算法是从点的角度来解决。若在解决问题过程中需要遍历图的所有点,则普里姆算法更好。
基本思想:
普里姆算法更像构建一棵树。联想我们构建二叉树的过程,从根节点出发,构建左右子树,再以左右子树为根节点,构建它们的左右子树。普里姆算法设一个点集V,初始时只有源点,从点集的点出发遍历所有以它们为起点的边,找到其中权值最小的边,且这条边的终点不在点集V中,然后将终点加入点集,再从点集V中的所有点出发,找一条权重最小的边。从点集中的点向外发散,构建起最小生成树。
本文测试算法用的无向数据网1

本文测试算法用的无向数据网2

直接上算法,请读者自行体会~

#include<stdio.h>
#include<stdlib.h>
#define MaxVertices 100
#define MaxNum 100
#define TRUE 1
#define FALSE 0
typedef struct enode {
int AdjVex;
int W;
int u;
struct enode* NextArc;
}ENode;
typedef struct graph {
int Vertices;
ENode** A;
}Graph;
void CreateGraph(Graph* g, int n) {
int i;
g->Vertices = n;
g->A = (ENode**)malloc(n * sizeof(ENode*));
for (i = 0; i < n; i++) {
g->A[i] = NULL;
}
}
ENode* NewENode(int vex, int weight, int u, ENode* nextarc) {
ENode* p;
p = (ENode*)malloc(sizeof(ENode));
p->AdjVex = vex;
p->W = weight;
p->u = u;
p->NextArc = nextarc;
return p;
}
int Exist(Graph* g, int u, int v) {
int n;
ENode* p;
n = g->Vertices;
if (u < 0 || u>n - 1) {
return 0;
}
for (p = g->A[u]; p && p->AdjVex != v; p = p->NextArc);
if (!p) {
return 0;
}
else {
return 1;
}
}
void Add(Graph* g, int u, int v, int w,int u1) {
int n;
ENode* p;
n = g->Vertices;
if (u<0 || v<0 || u>n - 1 || v>n - 1 || Exist(g, u, v)) {
printf(“BadInput\n”);
}
p = NewENode(v, w,u1,g->A[u]);
g->A[u] = p;
}
void Delete(Graph* g, int u, int v) {
int n = g->Vertices;
ENode* p, * q;
if (u > -1 && u < n) {
p = g->A[u];
q = NULL;
while (p && p->AdjVex != v) {
q = p;
p = p->NextArc;
}
if § {
if (q) {
q->NextArc = p->NextArc;
}
else {
g->A[u] = p->NextArc;
}
free§;
printf(“Delete Successfully!\n”);
}
else {
printf(“Cannot find!\n”);
}
}
else {
printf(“Bad Input!\n”);
}
}
void Prim(Graph* g, int k) {
int i, j, n = g->Vertices, b, minW, * V, count = -1, c, mini, J, U , uu;
int
nearest;
int
lowcost;
int
key;
nearest = (int*)malloc(nsizeof(int));
lowcost = (int
)malloc(nsizeof(int));
key = (int
)malloc(nsizeof(int));
V = (int
)malloc(nsizeof(int));
mini = (int
)malloc(nsizeof(int));
J = (int
)malloc(nsizeof(int));
U = (int
)malloc(nsizeof(int));
int mark[MaxVertices];
ENode
p;
if (k < 0 || k>n - 1) {
printf(“BAD INPUT !\n”); return;
}
for (i = 0; i < n; i++) {
nearest[i] = -1;
mark[i] = FALSE;
lowcost[i] = MaxNum;
}
mark[k] = TRUE;
lowcost[k] = 0; nearest[k] = k; key[0] = 0;
count++;
V[count] = k;
while (1) {
minW = 10000;
for (c = 0; c <= count; c++) {
p = g->A[V[c]];
while § {
if (mark[p->AdjVex] == FALSE) {
minW = p->W;
j = p->AdjVex;
uu = p->u;
break;
}
else {
p = p->NextArc;
}
}
while § {
p = p->NextArc;
if (p != NULL && p->W < minW && mark[p->AdjVex] == FALSE) {
minW = p->W;
j = p->AdjVex;
uu = p->u;
}
}
if (minW != 10000) {
mini[c] = minW;
J[c] = j;
U[c] = uu;
minW = 10000;
}
else {
mini[c] = minW;
}
}
minW = mini[0];
j = J[0];
uu = U[0];
for (c = 0; c <= count; c++) {
if (mini[c] < minW) {
minW = mini[c];
j = J[c];
uu = U[c];
}
}
if (minW==10000) {
break;
}
nearest[j] = j;
lowcost[j] = minW;
key[j] = uu;
count++;
V[count] = j;
mark[j] = TRUE;
}
for (b = 0; b < n; b++) {
printf("%-6d %-6d%-6d\n", key[b], lowcost[b], nearest[b]);
}
}
void PrintArrayMatrix(Graph* g) {
int i;
ENode* p;
for (i = 0; i < g->Vertices; i++) {
printf("%d: “, i);
for (p = g->A[i]; p != NULL; p = p->NextArc) {
printf(”[%d][%d]—>", p->AdjVex, p->W);
}
printf("\n");
}
printf("**********\n");
}
void main() {
Graph
g;
g = (Graph
)malloc(sizeof(Graph));
CreateGraph(g, 9);
/Add(g, 0, 1, 6, 0);
Add(g, 0, 3, 5,0);
Add(g, 0, 2, 1,0);
Add(g, 1, 0, 6,1);
Add(g, 1, 2, 5,1);
Add(g, 1, 4, 3,1);
Add(g, 2, 4, 6,2);
Add(g, 2, 3, 5,2);
Add(g, 2, 1, 5,2);
Add(g, 2, 5, 4,2);
Add(g, 2, 0, 1,2);
Add(g, 3, 2, 5,3);
Add(g, 3, 0, 5,3);
Add(g, 3, 5, 2,3);
Add(g, 4, 5, 6,4);
Add(g, 4, 2, 6,4);
Add(g, 4, 1, 3,4);
Add(g, 5, 4, 6,5);
Add(g, 5, 2, 4,5);
Add(g, 5, 3, 2, 5);
/
Add(g, 0, 5, 11, 0);
Add(g, 0, 1, 10, 0);
Add(g, 1, 0, 10, 1);
Add(g, 1, 6, 16, 1);
Add(g, 1, 8, 12, 1);
Add(g, 1, 2, 18, 1);
Add(g, 2, 3, 22, 2);
Add(g, 2, 8, 8, 2);
Add(g, 2, 1, 18, 2);
Add(g, 3, 4, 20, 3);
Add(g, 3, 7, 16, 3);
Add(g, 3, 6, 24, 3);
Add(g, 3, 8, 21, 3);
Add(g, 3, 2, 22, 3);
Add(g, 4, 5, 26, 4);
Add(g, 4, 3, 20, 4);
Add(g, 4, 7, 7, 4);
Add(g, 5, 4, 26, 5);
Add(g, 5, 6, 17, 5);
Add(g, 5, 0, 11, 5);
Add(g, 6, 3, 24, 6);
Add(g, 6, 7, 19, 6);
Add(g, 6, 5, 17, 6);
Add(g, 6, 1, 16, 6);
Add(g, 7, 6, 19, 7);
Add(g, 7, 3, 16, 7);
Add(g, 7, 4, 7, 7);
Add(g, 8, 3, 21, 8);
Add(g, 8, 2, 8, 8);
Add(g, 8, 1, 12, 8);
PrintArrayMatrix(g);
Prim(g,0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值