最小生成树算法C语言代码实例

在贪婪算法这一章提到了最小生成树的一些算法,首先是Kruskal算法,实现如下:

MST.h

代码如下:

#ifndef H_MST
#define H_MST

#define NODE node *
#define G graph *
#define MST edge **

/* the undirect graph start */
typedef struct _node {
 char data;
 int flag;
 struct _node *parent;
} node;

typedef struct _edge {
 node *A;
 node *B;
 int w;
} edge;

typedef struct _graph {
 node **nodelist;
 int nodeLen;
 edge **edgelist;
 int edgeLen;
} graph;

/* the undirect graph end */

int kruskal(G , edge *[]);

int makeset(NODE);

int find(NODE , NODE);

int merge(NODE , NODE);

int comp(const void *, const void *);

#endif

MST.c

代码如下:

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

int main(int argc, char *argv[])
{
 /* Construct the undirect connected graph */
 graph g;
 g.nodeLen = 6;
 g.edgeLen = 10;

node node_a, node_b, node_c, node_d, node_e, node_f;
 edge edge_1, edge_2, edge_3, edge_4, edge_5, edge_6, edge_7, edge_8, edge_9, edge_10;

node_a.data = 'a';
 node_a.flag = 0;
 node_a.parent = (node *)malloc(sizeof(node));
 node_b.data = 'b';
 node_b.flag = 0;
 node_b.parent = (node *)malloc(sizeof(node));
 node_c.data = 'c';
 node_c.flag = 0;
 node_c.parent = (node *)malloc(sizeof(node));
 node_d.data = 'd';
 node_d.flag = 0;
 node_d.parent = (node *)malloc(sizeof(node));
 node_e.data = 'e';
 node_e.flag = 0;
 node_e.parent = (node *)malloc(sizeof(node));
 node_f.data = 'f';
 node_f.flag = 0;
 node_f.parent = (node *)malloc(sizeof(node));

edge_1.A = &node_a;
 edge_1.B = &node_b;
 edge_1.w = 5;

edge_2.A = &node_a;
 edge_2.B = &node_c;
 edge_2.w = 6;

edge_3.A = &node_a;
 edge_3.B = &node_d;
 edge_3.w = 4;

edge_4.A = &node_b;
 edge_4.B = &node_c;
 edge_4.w = 1;

edge_5.A = &node_b;
 edge_5.B = &node_d;
 edge_5.w = 2;

edge_6.A = &node_c;
 edge_6.B = &node_d;
 edge_6.w = 2;

edge_7.A = &node_c;
 edge_7.B = &node_e;
 edge_7.w = 5;

edge_8.A = &node_c;
 edge_8.B = &node_f;
 edge_8.w = 3;

edge_9.A = &node_d;
 edge_9.B = &node_f;
 edge_9.w = 4;

edge_10.A = &node_e;
 edge_10.B = &node_f;
 edge_10.w = 4;

node **nodelist;
 nodelist = (node **)malloc(sizeof(node *) * g.nodeLen);
 edge **edgelist;
 edgelist = (edge **)malloc(sizeof(edge *) * g.edgeLen);

nodelist[0] = &node_a;
 nodelist[1] = &node_b;
 nodelist[2] = &node_c;
 nodelist[3] = &node_d;
 nodelist[4] = &node_e;
 nodelist[5] = &node_f;

edgelist[0] = &edge_1;
 edgelist[1] = &edge_2;
 edgelist[2] = &edge_3;
 edgelist[3] = &edge_4;
 edgelist[4] = &edge_5;
 edgelist[5] = &edge_6;
 edgelist[6] = &edge_7;
 edgelist[7] = &edge_8;
 edgelist[8] = &edge_9;
 edgelist[9] = &edge_10;

g.nodelist = nodelist;
 g.edgelist = edgelist;

edge *X[g.nodeLen-1];

int e = 0;
 while (e < g.edgeLen)
 {
  printf("%c-%c %d\n", g.edgelist[e]->A->data, g.edgelist[e]->B->data, g.edgelist[e]->w);
  e++;
 }

printf("------------------------------------------------------\n");

kruskal(&g, X);

e = 0;
 while (e < (g.nodeLen-1))
 {
  printf("%c-%c %d\n", X[e]->A->data, X[e]->B->data, X[e]->w);
  e++;
 }
}

int kruskal(G g, edge *pX[])
{
 int i, j;

/* Initially every disjoint set have one node */
 for (i = 0; i < g->nodeLen; i++)
  makeset(g->nodelist[i]);

/* sort the edgelist */
 qsort(g->edgelist, g->edgeLen, sizeof(edge *), comp);

int e = 0;
 while (e < g->edgeLen)
 {
  printf("%c-%c %d\n", g->edgelist[e]->A->data, g->edgelist[e]->B->data, g->edgelist[e]->w);
  e++;
 }

printf("------------------------------------------------------\n");

node da, db;
 da.parent = (node *)malloc(sizeof(node));
 db.parent = (node *)malloc(sizeof(node));

for (j = 0; j < g->edgeLen; j++)
 {
  find(g->edgelist[j]->A, &da);
  find(g->edgelist[j]->B, &db);

if (da.data != db.data)
  {
   merge(g->edgelist[j]->A, g->edgelist[j]->B);
   *pX++ = g->edgelist[j];
  }
 }
}

int makeset(NODE n)
{
 n->parent = n;
}

int find(NODE n, NODE ds)
{
 if (n->parent == n)
 {
  ds->data = n->data;
  ds->flag = 1;
  ds->parent = n->parent;
 }

if (n->parent != n)
  find(n->parent, ds);
}

int merge(NODE da, NODE db)
{
 if (da->flag)
  db->parent = da;
 else
  da->parent = db;
}

int comp(const void *ea, const void *eb)
{
 if ((*(edge **)ea)->w > (*(edge **)eb)->w) return 1;
 else if ((*(edge **)ea)->w == (*(edge **)eb)->w ) return 0;
 else return -1;
}

在实现这个算法的时候,真正体会到了测试的重要性。程序能成功编译只是完成了一小部分,必须经过反复的测试才能发布。

(0)

相关推荐

  • 使用C语言实现最小生成树求解的简单方法

    最小生成树Prim算法朴素版 有几点需要说明一下. 1.2个for循环都是从2开始的,因为一般我们默认开始就把第一个节点加入生成树,因此之后不需要再次寻找它. 2.lowcost[i]记录的是以节点i为终点的最小边权值.初始化时因为默认把第一个节点加入生成树,因此lowcost[i] = graph[1][i],即最小边权值就是各节点到1号节点的边权值. 3.mst[i]记录的是lowcost[i]对应的起点,这样有起点,有终点,即可唯一确定一条边了.初始化时mst[i] = 1,即每条边都是从

  • Prim(普里姆)算法求最小生成树的思想及C语言实例讲解

    Prim 算法思想: 从任意一顶点 v0 开始选择其最近顶点 v1 构成树 T1,再连接与 T1 最近顶点 v2 构成树 T2, 如此重复直到所有顶点均在所构成树中为止. 最小生成树(MST):权值最小的生成树. 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路.可以把边上的权值解释为线路的造价.则最小生成树表示使其造价最小的生成树. 构造网的最小生成树必须解决下面两个问题: 1.尽可能选取权值小的边,但不能构成回路: 2.选取n-1条恰当的边以连通n个顶点: MST性质:假设G=(V

  • 最小生成树算法C语言代码实例

    在贪婪算法这一章提到了最小生成树的一些算法,首先是Kruskal算法,实现如下: MST.h 复制代码 代码如下: #ifndef H_MST#define H_MST #define NODE node *#define G graph *#define MST edge ** /* the undirect graph start */typedef struct _node { char data; int flag; struct _node *parent;} node; typede

  • PHP常见算法合集代码实例

    许多人都说 算法是程序的核心,一个程序的好于差,关键是这个程序算法的优劣,下面是一些常用的算法和实例,大家可以好好学习下 一.文件夹遍历 <?php function allFile($path = __DIR__, $level = 1) { if (is_dir($path) && is_readable($path)) { if($pd = opendir($path)) { while (($file = readdir($pd)) !== false) { if($file

  • 在Golang中使用C语言代码实例

    cgo 使得在 Golang 中可以使用 C 代码. Hello World 为了有一个较为直观的了解,我们来看一个简单的例子,创建文件 main.go: 复制代码 代码如下: package main   /* #include <stdio.h>   void sayHi() {     printf("Hi"); } */ import "C"   func main() {     C.sayHi() } 执行程序: 复制代码 代码如下: go

  • Java sha1散列算法原理及代码实例

    直接调用HashKit.sha1(String str)方法就可以了,,返回的是16进制的字符串长度是40, 也就是用md.digest()方法解析出来的字节数是160字节长度. 而MD5散列算法生成的字节数是128字节长度,返回的16进制的字符长度是32位 代码如下 public class HashKit { private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray(); public stati

  • python根据unicode判断语言类型实例代码

    本文实例主要实现的是python根据unicode判断语言类型,具体如下. 实例代码: def is_chinese(uchar): """判断一个unicode是否是汉字""" if uchar >= u'\u4e00' and uchar<=u'\u9fa5': return True else: return False def is_number(uchar): """判断一个unicode是否是

  • Java语言字典序排序算法解析及代码示例

    字典序法就是按照字典排序的思想逐一产生所有排列. 在数学中,字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法. 这种泛化主要在于定义有序完全有序集合(通常称为字母表)的元素的序列(通常称为计算机科学中的单词)的总顺序. 对于数字1.2.3......n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的.例如对于5个数字的排列 12354和12345,排列12345在前,排列12354在后.按照这样的规定,5个数字的所有的

  • js图数据结构处理 迪杰斯特拉算法代码实例

    这篇文章主要介绍了js图数据结构处理 迪杰斯特拉算法代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 /*//1.确定数据结构, mapf[i][j] 为点i到点j的距离 [ Infinity 2 5 Infinity Infinity Infinity Infinity 2 6 Infinity Infinity Infinity Infinity 7 1 Infinity Infinity 2 Infinity 4 Infinity

  • Java二分查找算法实现代码实例

    这篇文章主要介绍了Java二分查找算法实现代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 二分查找: 两种方式: 非递归方式和递归方式 主要思路: 对于已排序的数组(先假定是从小到大排序), 先定义两个"指针", 一个"指向"首元素low, 一个"指向"末尾元素high. 然后, 开始折半比较, 即让要查找的数与数组中间的元素(索引为 low+high/2)比较. 若要查找的数比中间数小

  • JavaScript多种滤镜算法实现代码实例

    这篇文章主要介绍了JavaScript多种滤镜算法实现代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.灰色滤镜 设定R,G,B值相等 function makeGray(img){ for(var pixel of img.values()){ var avg = (pixel.getRed()+pixel.getGreen()+pixel.getBlue())/3; pixel.setRed(avg); pixel.setGree

  • 基于javascript实现获取最短路径算法代码实例

    这篇文章主要介绍了基于javascript实现获取最短路径算法代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下 //A算法 自动寻路 路径 class GetAutoPath{ constructor(id, map, sPos, ePos, mapArr){ //this.type = id.type; this.id = id; this.map = map; this.sPos = sPos; this.ePos = eP

随机推荐