这里讲最后一个最小生成树
一、最小生成树
一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。
简单来说就是把n个节点连成一个连通图所需要的最小权重和,用生活实际来说,就是有n个家庭,每两个家庭之间距离不同,现在要铺设水管,如何做到用最少的水管让每家每户都有水用。
这里主要叙述一下prim算法。
二、算法描述:
准备:申请三个数组,一个存放已连接队列,一个存放权重,一个存放连接点(哪两个点相连)
1、初始化:将所有已连接队列置为空,权重数组全部置为与起点相连的权重,连接点置为起点
2、遍历权重数组,找出最小的值和相连接的点,
3、将2中找到的点加入已连接队列,更新剩余点到任意已连接点的权重
4、重复2.3两步,直至待连接队列为空
算法结束。
三、图解
四、实现代码:
template <class Weight, int graph size> void Network < Weight, graph size > :: minimal spanning(Vertex source, Network<Weight, graph size> &tree) const /* Post: The Network tree contains a minimal spanning tree for the connected component of the original Network that contains vertex source. */ { tree.make empty(count); bool component[graph size]; // Vertices in set X Weight distance[graph size]; // Distances of vertices adjacent to X Vertex neighbor[graph size]; // Nearest neighbor in set X Vertex w; for (w = 0; w < count; w++) { component[w] = false; distance[w] = adjacency[source][w]; neighbor[w] = source; } component[source] = true; // source alone is in the set X. for (int i = 1; i < count; i++) { Vertex v; // Add one vertex v to X on each pass. Weight min = innity; for (w = 0; w < count; w++) if (!component[w]) if (distance[w] < min) { v = w; min = distance[w]; } if (min < innity) { component[v] = true; tree.add edge(v, neighbor[v], distance[v]); for (w = 0; w < count; w++) if (!component[w]) if (adjacency[v][w] < distance[w]) { distance[w] = adjacency[v][w]; neighbor[w] = v; } } else break; // finished a component in disconnected graph } }
这个代码是直接copy下来的,没有测试过,大家测试发现问题告诉我哈~
以上。
数据结构大概就讲了这么多内容,对这门课的感受就是主要偏向于理论算法结构,对于代码的实现并不是很强调,不过这些内容都是挺有用的,大部分的数据结构在库里大都有现成的函数,效率也比我们写的效率高得多。学这些的原因大概是为了我们的基础吧(至少我是这么认为的)。
还有很幸运能成为丽萍姐姐的学生啦,人超好的一位老师,虽然很舍不得,但还是很开心能够在这个班级学了一个学期,学到了很多,感谢!
2016/06/25